更新管理员登录和鉴权逻辑,优化用户体验;重构相关API以支持更安全的身份验证;调整数据库初始化以兼容新字段,确保用户信息安全;修复部分组件样式和功能,提升整体可用性。
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { requireAdminResponse } from '@/lib/admin-auth'
|
||||
|
||||
// 获取书籍目录
|
||||
const BOOK_DIR = path.join(process.cwd(), 'book')
|
||||
@@ -14,6 +15,8 @@ const BOOK_DIR = path.join(process.cwd(), 'book')
|
||||
* GET - 获取所有章节列表
|
||||
*/
|
||||
export async function GET(request: Request) {
|
||||
const authErr = requireAdminResponse(request)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const includeContent = searchParams.get('content') === 'true'
|
||||
@@ -274,6 +277,8 @@ export async function GET(request: Request) {
|
||||
* POST - 更新章节设置
|
||||
*/
|
||||
export async function POST(request: Request) {
|
||||
const authErr = requireAdminResponse(request)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await request.json()
|
||||
const { action, chapterId, data } = body
|
||||
|
||||
@@ -5,11 +5,14 @@ import { NextRequest, NextResponse } from 'next/server'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import { requireAdminResponse } from '@/lib/admin-auth'
|
||||
|
||||
const BOOK_DIR = path.join(process.cwd(), 'book')
|
||||
|
||||
// GET: 获取所有章节列表
|
||||
export async function GET(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const chapters = getAllChapters()
|
||||
|
||||
@@ -28,6 +31,8 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
// POST: 创建新章节
|
||||
export async function POST(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { title, content, category, tags } = body
|
||||
@@ -70,6 +75,8 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
// PUT: 更新章节
|
||||
export async function PUT(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { id, title, content, category, tags } = body
|
||||
@@ -97,6 +104,8 @@ export async function PUT(req: NextRequest) {
|
||||
|
||||
// DELETE: 删除章节
|
||||
export async function DELETE(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const id = searchParams.get('id')
|
||||
|
||||
9
app/api/admin/logout/route.ts
Normal file
9
app/api/admin/logout/route.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getAdminCookieName, getAdminCookieOptions } from '@/lib/admin-auth'
|
||||
|
||||
export async function POST(_req: NextRequest) {
|
||||
const res = NextResponse.json({ success: true })
|
||||
const opts = getAdminCookieOptions()
|
||||
res.cookies.set(getAdminCookieName(), '', { ...opts, maxAge: 0 })
|
||||
return res
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
// 付费模块管理API
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { requireAdminResponse } from '@/lib/admin-auth'
|
||||
|
||||
// 模拟订单数据
|
||||
let orders = [
|
||||
@@ -29,6 +30,8 @@ let orders = [
|
||||
|
||||
// GET: 获取订单列表
|
||||
export async function GET(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
const { searchParams } = new URL(req.url)
|
||||
const status = searchParams.get('status')
|
||||
const page = parseInt(searchParams.get('page') || '1')
|
||||
@@ -71,6 +74,8 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
// POST: 创建订单(手动)
|
||||
export async function POST(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { userId, userName, amount, note } = body
|
||||
@@ -110,6 +115,8 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
// PUT: 更新订单状态
|
||||
export async function PUT(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { orderId, status, note } = body
|
||||
@@ -148,6 +155,8 @@ export async function PUT(req: NextRequest) {
|
||||
|
||||
// DELETE: 删除订单
|
||||
export async function DELETE(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const orderId = searchParams.get('id')
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 分销模块管理API
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { requireAdminResponse } from '@/lib/admin-auth'
|
||||
|
||||
// 模拟分销数据
|
||||
let referralRecords = [
|
||||
@@ -52,6 +53,8 @@ let commissionRecords = [
|
||||
|
||||
// GET: 获取分销概览或列表
|
||||
export async function GET(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
const { searchParams } = new URL(req.url)
|
||||
const type = searchParams.get('type') || 'list'
|
||||
const page = parseInt(searchParams.get('page') || '1')
|
||||
@@ -95,6 +98,8 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
// POST: 创建分销记录或处理佣金
|
||||
export async function POST(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { action, data } = body
|
||||
@@ -170,6 +175,8 @@ export async function POST(req: NextRequest) {
|
||||
|
||||
// PUT: 更新分销记录
|
||||
export async function PUT(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await req.json()
|
||||
const { referrerId, status, commissionRate, note } = body
|
||||
@@ -205,6 +212,8 @@ export async function PUT(req: NextRequest) {
|
||||
|
||||
// DELETE: 删除分销记录
|
||||
export async function DELETE(req: NextRequest) {
|
||||
const authErr = requireAdminResponse(req)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const { searchParams } = new URL(req.url)
|
||||
const referrerId = searchParams.get('id')
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
// app/api/admin/route.ts
|
||||
// 后台管理API入口
|
||||
// 后台管理API入口:登录与鉴权(账号密码从环境变量读取,默认 admin / admin123)
|
||||
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import {
|
||||
verifyAdminToken,
|
||||
getAdminTokenFromRequest,
|
||||
verifyAdminCredentials,
|
||||
getAdminCredentials,
|
||||
createAdminToken,
|
||||
getAdminCookieName,
|
||||
getAdminCookieOptions,
|
||||
} from '@/lib/admin-auth'
|
||||
|
||||
// 验证管理员权限
|
||||
function verifyAdmin(req: NextRequest) {
|
||||
const token = req.headers.get('Authorization')?.replace('Bearer ', '')
|
||||
|
||||
// TODO: 实现真实的token验证
|
||||
if (!token || token !== 'admin-token-secret') {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
function requireAdmin(req: NextRequest): boolean {
|
||||
const token = getAdminTokenFromRequest(req)
|
||||
return verifyAdminToken(token)
|
||||
}
|
||||
|
||||
// GET: 获取后台概览数据
|
||||
// GET: 获取后台概览数据(需已登录)
|
||||
export async function GET(req: NextRequest) {
|
||||
if (!verifyAdmin(req)) {
|
||||
if (!requireAdmin(req)) {
|
||||
return NextResponse.json(
|
||||
{ error: '未授权访问' },
|
||||
{ error: '未授权访问,请先登录' },
|
||||
{ status: 401 }
|
||||
)
|
||||
}
|
||||
@@ -58,27 +60,31 @@ export async function GET(req: NextRequest) {
|
||||
return NextResponse.json(overview)
|
||||
}
|
||||
|
||||
// POST: 管理员登录
|
||||
// POST: 管理员登录(账号密码从环境变量 ADMIN_USERNAME / ADMIN_PASSWORD 读取,默认 admin / admin123)
|
||||
export async function POST(req: NextRequest) {
|
||||
const body = await req.json()
|
||||
const { username, password } = body
|
||||
|
||||
// TODO: 实现真实的登录验证
|
||||
if (username === 'admin' && password === 'admin123') {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
token: 'admin-token-secret',
|
||||
user: {
|
||||
id: 'admin',
|
||||
username: 'admin',
|
||||
role: 'admin',
|
||||
name: '卡若'
|
||||
}
|
||||
})
|
||||
if (!username || !password) {
|
||||
return NextResponse.json(
|
||||
{ error: '请输入用户名和密码' },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: '用户名或密码错误' },
|
||||
{ status: 401 }
|
||||
)
|
||||
if (!verifyAdminCredentials(String(username).trim(), String(password))) {
|
||||
return NextResponse.json(
|
||||
{ error: '用户名或密码错误' },
|
||||
{ status: 401 }
|
||||
)
|
||||
}
|
||||
|
||||
const token = createAdminToken()
|
||||
const res = NextResponse.json({
|
||||
success: true,
|
||||
user: { id: 'admin', username: getAdminCredentials().username, role: 'admin', name: '卡若' },
|
||||
})
|
||||
const opts = getAdminCookieOptions()
|
||||
res.cookies.set(getAdminCookieName(), token, opts)
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
import { query } from '@/lib/db'
|
||||
import { createTransfer } from '@/lib/wechat-transfer'
|
||||
import { requireAdminResponse } from '@/lib/admin-auth'
|
||||
|
||||
// 获取所有提现记录
|
||||
export async function GET(request: Request) {
|
||||
const authErr = requireAdminResponse(request)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const { searchParams } = new URL(request.url)
|
||||
const status = searchParams.get('status') // pending, success, failed, all
|
||||
@@ -84,6 +87,8 @@ export async function GET(request: Request) {
|
||||
|
||||
// 处理提现(审批/拒绝)
|
||||
export async function PUT(request: Request) {
|
||||
const authErr = requireAdminResponse(request)
|
||||
if (authErr) return authErr
|
||||
try {
|
||||
const body = await request.json()
|
||||
const { id, action, reason } = body // action: approve, reject
|
||||
|
||||
Reference in New Issue
Block a user