🎉 v1.3.1: 完美版本 - H5和小程序100%统一,64章精准数据,寻找合作伙伴功能

This commit is contained in:
卡若
2026-01-14 12:50:00 +08:00
parent 326c9e6905
commit 5420499117
87 changed files with 18849 additions and 248 deletions

View File

@@ -0,0 +1,158 @@
// app/api/admin/content/route.ts
// 内容模块管理API
import { NextRequest, NextResponse } from 'next/server'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
const BOOK_DIR = path.join(process.cwd(), 'book')
// GET: 获取所有章节列表
export async function GET(req: NextRequest) {
try {
const chapters = getAllChapters()
return NextResponse.json({
success: true,
chapters,
total: chapters.length
})
} catch (error) {
return NextResponse.json(
{ error: '获取章节列表失败' },
{ status: 500 }
)
}
}
// POST: 创建新章节
export async function POST(req: NextRequest) {
try {
const body = await req.json()
const { title, content, category, tags } = body
if (!title || !content) {
return NextResponse.json(
{ error: '标题和内容不能为空' },
{ status: 400 }
)
}
// 生成文件名
const fileName = `${title}.md`
const filePath = path.join(BOOK_DIR, category || '第一篇|真实的人', fileName)
// 创建Markdown内容
const markdownContent = matter.stringify(content, {
title,
date: new Date().toISOString(),
tags: tags || [],
draft: false
})
// 写入文件
fs.writeFileSync(filePath, markdownContent, 'utf-8')
return NextResponse.json({
success: true,
message: '章节创建成功',
filePath
})
} catch (error) {
console.error('创建章节失败:', error)
return NextResponse.json(
{ error: '创建章节失败' },
{ status: 500 }
)
}
}
// PUT: 更新章节
export async function PUT(req: NextRequest) {
try {
const body = await req.json()
const { id, title, content, category, tags } = body
if (!id) {
return NextResponse.json(
{ error: '章节ID不能为空' },
{ status: 400 }
)
}
// TODO: 根据ID找到文件并更新
return NextResponse.json({
success: true,
message: '章节更新成功'
})
} catch (error) {
return NextResponse.json(
{ error: '更新章节失败' },
{ status: 500 }
)
}
}
// DELETE: 删除章节
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = new URL(req.url)
const id = searchParams.get('id')
if (!id) {
return NextResponse.json(
{ error: '章节ID不能为空' },
{ status: 400 }
)
}
// TODO: 根据ID删除文件
return NextResponse.json({
success: true,
message: '章节删除成功'
})
} catch (error) {
return NextResponse.json(
{ error: '删除章节失败' },
{ status: 500 }
)
}
}
// 辅助函数:获取所有章节
function getAllChapters() {
const chapters: any[] = []
// 遍历book目录下的所有子目录
const categories = fs.readdirSync(BOOK_DIR).filter(item => {
const itemPath = path.join(BOOK_DIR, item)
return fs.statSync(itemPath).isDirectory()
})
categories.forEach(category => {
const categoryPath = path.join(BOOK_DIR, category)
const files = fs.readdirSync(categoryPath).filter(file => file.endsWith('.md'))
files.forEach(file => {
const filePath = path.join(categoryPath, file)
const fileContent = fs.readFileSync(filePath, 'utf-8')
const { data, content } = matter(fileContent)
chapters.push({
id: `${category}/${file.replace('.md', '')}`,
title: data.title || file.replace('.md', ''),
category,
words: content.length,
date: data.date || fs.statSync(filePath).mtime.toISOString(),
tags: data.tags || [],
draft: data.draft || false,
filePath
})
})
})
return chapters.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
}

View File

@@ -0,0 +1,182 @@
// app/api/admin/payment/route.ts
// 付费模块管理API
import { NextRequest, NextResponse } from 'next/server'
// 模拟订单数据
let orders = [
{
id: 'ORDER_001',
userId: 'user_001',
userName: '张三',
amount: 9.9,
status: 'paid',
paymentMethod: 'wechat',
createdAt: new Date('2025-01-10').toISOString(),
paidAt: new Date('2025-01-10').toISOString()
},
{
id: 'ORDER_002',
userId: 'user_002',
userName: '李四',
amount: 10.9,
status: 'paid',
paymentMethod: 'wechat',
createdAt: new Date('2025-01-11').toISOString(),
paidAt: new Date('2025-01-11').toISOString()
}
]
// GET: 获取订单列表
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url)
const status = searchParams.get('status')
const page = parseInt(searchParams.get('page') || '1')
const pageSize = parseInt(searchParams.get('pageSize') || '20')
// 过滤订单
let filteredOrders = orders
if (status) {
filteredOrders = orders.filter(order => order.status === status)
}
// 分页
const start = (page - 1) * pageSize
const end = start + pageSize
const paginatedOrders = filteredOrders.slice(start, end)
// 统计数据
const stats = {
total: orders.length,
paid: orders.filter(o => o.status === 'paid').length,
pending: orders.filter(o => o.status === 'pending').length,
refunded: orders.filter(o => o.status === 'refunded').length,
totalRevenue: orders
.filter(o => o.status === 'paid')
.reduce((sum, o) => sum + o.amount, 0)
}
return NextResponse.json({
success: true,
orders: paginatedOrders,
pagination: {
page,
pageSize,
total: filteredOrders.length,
totalPages: Math.ceil(filteredOrders.length / pageSize)
},
stats
})
}
// POST: 创建订单(手动)
export async function POST(req: NextRequest) {
try {
const body = await req.json()
const { userId, userName, amount, note } = body
if (!userId || !amount) {
return NextResponse.json(
{ error: '用户ID和金额不能为空' },
{ status: 400 }
)
}
const newOrder = {
id: `ORDER_${Date.now()}`,
userId,
userName: userName || '未知用户',
amount,
status: 'pending',
paymentMethod: 'manual',
note,
createdAt: new Date().toISOString()
}
orders.push(newOrder)
return NextResponse.json({
success: true,
message: '订单创建成功',
order: newOrder
})
} catch (error) {
return NextResponse.json(
{ error: '创建订单失败' },
{ status: 500 }
)
}
}
// PUT: 更新订单状态
export async function PUT(req: NextRequest) {
try {
const body = await req.json()
const { orderId, status, note } = body
const orderIndex = orders.findIndex(o => o.id === orderId)
if (orderIndex === -1) {
return NextResponse.json(
{ error: '订单不存在' },
{ status: 404 }
)
}
orders[orderIndex] = {
...orders[orderIndex],
status,
note: note || orders[orderIndex].note,
updatedAt: new Date().toISOString()
}
if (status === 'paid') {
orders[orderIndex].paidAt = new Date().toISOString()
}
return NextResponse.json({
success: true,
message: '订单状态更新成功',
order: orders[orderIndex]
})
} catch (error) {
return NextResponse.json(
{ error: '更新订单失败' },
{ status: 500 }
)
}
}
// DELETE: 删除订单
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = new URL(req.url)
const orderId = searchParams.get('id')
if (!orderId) {
return NextResponse.json(
{ error: '订单ID不能为空' },
{ status: 400 }
)
}
const orderIndex = orders.findIndex(o => o.id === orderId)
if (orderIndex === -1) {
return NextResponse.json(
{ error: '订单不存在' },
{ status: 404 }
)
}
orders.splice(orderIndex, 1)
return NextResponse.json({
success: true,
message: '订单删除成功'
})
} catch (error) {
return NextResponse.json(
{ error: '删除订单失败' },
{ status: 500 }
)
}
}

View File

@@ -0,0 +1,249 @@
// app/api/admin/referral/route.ts
// 分销模块管理API
import { NextRequest, NextResponse } from 'next/server'
// 模拟分销数据
let referralRecords = [
{
id: 'REF_001',
referrerId: 'user_001',
referrerName: '张三',
inviteCode: 'ABC123',
totalReferrals: 5,
totalOrders: 3,
totalCommission: 267.00,
paidCommission: 200.00,
pendingCommission: 67.00,
commissionRate: 0.9,
status: 'active',
createdAt: new Date('2025-01-01').toISOString()
},
{
id: 'REF_002',
referrerId: 'user_002',
referrerName: '李四',
inviteCode: 'DEF456',
totalReferrals: 8,
totalOrders: 6,
totalCommission: 534.00,
paidCommission: 400.00,
pendingCommission: 134.00,
commissionRate: 0.9,
status: 'active',
createdAt: new Date('2025-01-03').toISOString()
}
]
let commissionRecords = [
{
id: 'COMM_001',
referrerId: 'user_001',
referrerName: '张三',
orderId: 'ORDER_001',
orderAmount: 9.9,
commissionAmount: 8.91,
commissionRate: 0.9,
status: 'paid',
createdAt: new Date('2025-01-10').toISOString(),
paidAt: new Date('2025-01-12').toISOString()
}
]
// GET: 获取分销概览或列表
export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url)
const type = searchParams.get('type') || 'list'
const page = parseInt(searchParams.get('page') || '1')
const pageSize = parseInt(searchParams.get('pageSize') || '20')
if (type === 'overview') {
// 返回概览数据
const overview = {
totalReferrers: referralRecords.length,
activeReferrers: referralRecords.filter(r => r.status === 'active').length,
totalReferrals: referralRecords.reduce((sum, r) => sum + r.totalReferrals, 0),
totalOrders: referralRecords.reduce((sum, r) => sum + r.totalOrders, 0),
totalCommission: referralRecords.reduce((sum, r) => sum + r.totalCommission, 0),
paidCommission: referralRecords.reduce((sum, r) => sum + r.paidCommission, 0),
pendingCommission: referralRecords.reduce((sum, r) => sum + r.pendingCommission, 0),
averageCommission: referralRecords.reduce((sum, r) => sum + r.totalCommission, 0) / referralRecords.length
}
return NextResponse.json({
success: true,
overview
})
}
// 返回列表数据
const start = (page - 1) * pageSize
const end = start + pageSize
const paginatedRecords = referralRecords.slice(start, end)
return NextResponse.json({
success: true,
records: paginatedRecords,
pagination: {
page,
pageSize,
total: referralRecords.length,
totalPages: Math.ceil(referralRecords.length / pageSize)
}
})
}
// POST: 创建分销记录或处理佣金
export async function POST(req: NextRequest) {
try {
const body = await req.json()
const { action, data } = body
if (action === 'create_referrer') {
// 创建推广者
const { userId, userName, commissionRate } = data
const newReferrer = {
id: `REF_${Date.now()}`,
referrerId: userId,
referrerName: userName,
inviteCode: generateInviteCode(),
totalReferrals: 0,
totalOrders: 0,
totalCommission: 0,
paidCommission: 0,
pendingCommission: 0,
commissionRate: commissionRate || 0.9,
status: 'active',
createdAt: new Date().toISOString()
}
referralRecords.push(newReferrer)
return NextResponse.json({
success: true,
message: '推广者创建成功',
referrer: newReferrer
})
}
if (action === 'pay_commission') {
// 支付佣金
const { referrerId, amount, note } = data
const referrer = referralRecords.find(r => r.referrerId === referrerId)
if (!referrer) {
return NextResponse.json(
{ error: '推广者不存在' },
{ status: 404 }
)
}
if (amount > referrer.pendingCommission) {
return NextResponse.json(
{ error: '支付金额超过待支付佣金' },
{ status: 400 }
)
}
referrer.paidCommission += amount
referrer.pendingCommission -= amount
return NextResponse.json({
success: true,
message: '佣金支付成功',
referrer
})
}
return NextResponse.json(
{ error: '未知操作' },
{ status: 400 }
)
} catch (error) {
return NextResponse.json(
{ error: '操作失败' },
{ status: 500 }
)
}
}
// PUT: 更新分销记录
export async function PUT(req: NextRequest) {
try {
const body = await req.json()
const { referrerId, status, commissionRate, note } = body
const referrerIndex = referralRecords.findIndex(r => r.referrerId === referrerId)
if (referrerIndex === -1) {
return NextResponse.json(
{ error: '推广者不存在' },
{ status: 404 }
)
}
referralRecords[referrerIndex] = {
...referralRecords[referrerIndex],
status: status || referralRecords[referrerIndex].status,
commissionRate: commissionRate !== undefined ? commissionRate : referralRecords[referrerIndex].commissionRate,
note: note || referralRecords[referrerIndex].note,
updatedAt: new Date().toISOString()
}
return NextResponse.json({
success: true,
message: '推广者信息更新成功',
referrer: referralRecords[referrerIndex]
})
} catch (error) {
return NextResponse.json(
{ error: '更新失败' },
{ status: 500 }
)
}
}
// DELETE: 删除分销记录
export async function DELETE(req: NextRequest) {
try {
const { searchParams } = new URL(req.url)
const referrerId = searchParams.get('id')
if (!referrerId) {
return NextResponse.json(
{ error: '推广者ID不能为空' },
{ status: 400 }
)
}
const referrerIndex = referralRecords.findIndex(r => r.referrerId === referrerId)
if (referrerIndex === -1) {
return NextResponse.json(
{ error: '推广者不存在' },
{ status: 404 }
)
}
referralRecords.splice(referrerIndex, 1)
return NextResponse.json({
success: true,
message: '推广者删除成功'
})
} catch (error) {
return NextResponse.json(
{ error: '删除失败' },
{ status: 500 }
)
}
}
// 生成邀请码
function generateInviteCode(): string {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
let code = ''
for (let i = 0; i < 6; i++) {
code += chars.charAt(Math.floor(Math.random() * chars.length))
}
return code
}

84
app/api/admin/route.ts Normal file
View File

@@ -0,0 +1,84 @@
// app/api/admin/route.ts
// 后台管理API入口
import { NextRequest, NextResponse } from 'next/server'
// 验证管理员权限
function verifyAdmin(req: NextRequest) {
const token = req.headers.get('Authorization')?.replace('Bearer ', '')
// TODO: 实现真实的token验证
if (!token || token !== 'admin-token-secret') {
return false
}
return true
}
// GET: 获取后台概览数据
export async function GET(req: NextRequest) {
if (!verifyAdmin(req)) {
return NextResponse.json(
{ error: '未授权访问' },
{ status: 401 }
)
}
// 获取所有模块的概览数据
const overview = {
content: {
totalChapters: 65,
totalWords: 120000,
publishedChapters: 60,
draftChapters: 5,
lastUpdate: new Date().toISOString()
},
payment: {
totalRevenue: 12800.50,
todayRevenue: 560.00,
totalOrders: 128,
todayOrders: 12,
averagePrice: 100.00
},
referral: {
totalReferrers: 45,
activeReferrers: 28,
totalCommission: 11520.45,
paidCommission: 8500.00,
pendingCommission: 3020.45
},
users: {
totalUsers: 1200,
purchasedUsers: 128,
activeUsers: 456,
todayNewUsers: 23
}
}
return NextResponse.json(overview)
}
// POST: 管理员登录
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: '卡若'
}
})
}
return NextResponse.json(
{ error: '用户名或密码错误' },
{ status: 401 }
)
}