feat: 完整重构小程序匹配功能 + 修复UI对齐 + 文章数据API

主要更新:
1. 按H5网页端完全重构匹配功能(match页面)
   - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募
   - 资源对接等类型弹出手机号/微信号输入框
   - 去掉重新匹配按钮,改为返回按钮

2. 修复所有卡片对齐和宽度问题
   - 目录页附录卡片居中
   - 首页阅读进度卡片满宽度
   - 我的页面菜单卡片对齐
   - 推广中心分享卡片统一宽度

3. 修复目录页图标和文字对齐
   - section-icon固定40rpx宽高
   - section-title与图标垂直居中

4. 更新真实完整文章标题(62篇)
   - 从book目录读取真实markdown文件名
   - 替换之前的简化标题

5. 新增文章数据API
   - /api/db/chapters - 获取完整书籍结构
   - 支持按ID获取单篇文章内容
This commit is contained in:
卡若
2026-01-21 15:49:12 +08:00
parent 1ee25e3dab
commit b60edb3d47
197 changed files with 34430 additions and 7345 deletions

View File

@@ -1,59 +1,74 @@
/**
* 微信支付回调通知 API
* 基于 Universal_Payment_Module v4.0 设计
*
* POST /api/payment/wechat/notify
*/
import { type NextRequest, NextResponse } from "next/server"
import { WechatPayService } from "@/lib/payment/wechat"
import { PaymentFactory, SignatureError } from "@/lib/payment"
// 确保网关已注册
import "@/lib/payment/wechat"
export async function POST(request: NextRequest) {
try {
// 获取XML原始数据
const xmlData = await request.text()
const wechat = new WechatPayService({
appId: process.env.WECHAT_APP_ID || "wx432c93e275548671",
appSecret: process.env.WECHAT_APP_SECRET || "25b7e7fdb7998e5107e242ebb6ddabd0",
mchId: process.env.WECHAT_MCH_ID || "1318592501",
apiKey: process.env.WECHAT_API_KEY || "wx3e31b068be59ddc131b068be59ddc2",
notifyUrl: "",
})
console.log("[Wechat Notify] 收到回调:", xmlData.slice(0, 200))
// 解析XML数据
const params = await wechat["parseXML"](xmlData)
// 创建微信支付网关
const gateway = PaymentFactory.create("wechat_native")
// 验证签名
const isValid = wechat.verifySign(params)
try {
// 解析并验证回调数据
const notifyResult = gateway.parseNotify(xmlData)
if (!isValid) {
console.error("[v0] WeChat signature verification failed")
return new NextResponse(
"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>",
{
headers: { "Content-Type": "application/xml" },
},
)
}
if (notifyResult.status === "paid") {
console.log("[Wechat Notify] 支付成功:", {
tradeSn: notifyResult.tradeSn,
platformSn: notifyResult.platformSn,
amount: notifyResult.payAmount / 100, // 转换为元
payTime: notifyResult.payTime,
})
const { out_trade_no, result_code, total_fee, openid } = params
// TODO: 更新订单状态
// await OrderService.updateStatus(notifyResult.tradeSn, 'paid')
if (result_code === "SUCCESS") {
console.log("[v0] WeChat payment success:", {
orderId: out_trade_no,
amount: Number.parseInt(total_fee) / 100,
openid,
// TODO: 解锁内容/开通权限
// await ContentService.unlockForUser(notifyResult.attach?.userId, notifyResult.attach?.productId)
// TODO: 分配佣金(如果有推荐人)
// if (notifyResult.attach?.referralCode) {
// await ReferralService.distributeCommission(notifyResult)
// }
} else {
console.log("[Wechat Notify] 支付失败:", notifyResult)
}
// 返回成功响应
return new NextResponse(gateway.successResponse(), {
headers: { "Content-Type": "application/xml" },
})
// TODO: 更新订单状态、解锁内容、分配佣金
} catch (error) {
if (error instanceof SignatureError) {
console.error("[Wechat Notify] 签名验证失败")
return new NextResponse(gateway.failResponse(), {
headers: { "Content-Type": "application/xml" },
})
}
throw error
}
return new NextResponse(
"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
{
headers: { "Content-Type": "application/xml" },
},
)
} catch (error) {
console.error("[v0] WeChat notify error:", error)
return new NextResponse(
"<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统错误]]></return_msg></xml>",
{
headers: { "Content-Type": "application/xml" },
},
)
console.error("[Wechat Notify] 处理失败:", error)
// 返回失败响应
const failXml = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[系统错误]]></return_msg></xml>'
return new NextResponse(failXml, {
headers: { "Content-Type": "application/xml" },
})
}
}