Ver código fonte

fix(wechat-pay): 移除time_expire避免非法字符错误

MyFramework User 3 meses atrás
pai
commit
1643493da2
3 arquivos alterados com 241 adições e 10 exclusões
  1. 118 0
      deploy-local.sh
  2. 123 0
      deploy-remote.sh
  3. 0 10
      server/src/modules/payment/payment.service.ts

+ 118 - 0
deploy-local.sh

@@ -0,0 +1,118 @@
+#!/bin/bash
+# 本地编译 + 传送到线上部署脚本
+# 用法: bash deploy-local.sh
+
+set -e
+
+# ========== 配置 ==========
+SERVER_IP="8.159.134.106"
+SERVER_PORT="22622"
+SERVER_USER="root"
+SERVER_PATH="/data/ai/audio_codebuddy"
+FRONTEND_PATH="/data/ai/frontend"
+SSH_OPTS="-p $SERVER_PORT -o StrictHostKeyChecking=no"
+
+# ========== 颜色输出 ==========
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
+
+# ========== 检查 ==========
+if ! command -v rsync &> /dev/null; then
+    log_warn "rsync 未安装,尝试安装..."
+    if [[ "$OSTYPE" == "darwin"* ]]; then
+        brew install rsync
+    else
+        sudo apt-get install -y rsync
+    fi
+fi
+
+# ========== 1. 提交代码 ==========
+log_info "========== 1. 提交代码 =========="
+git status --short
+
+read -p "是否提交所有改动? (y/n): " confirm
+if [[ "$confirm" == "y" ]]; then
+    git add -A
+    read -p "输入提交信息: " commit_msg
+    git commit -m "$commit_msg"
+    git push git@git.rrbrr.com:caojunfei/audio_codebuddy.git master
+fi
+
+# ========== 2. 构建前端 ==========
+log_info "========== 2. 构建前端 =========="
+cd my-uniapp-vue3
+npm install
+npm run build:h5
+cd ..
+
+# ========== 3. 构建后端 ==========
+log_info "========== 3. 构建后端 =========="
+cd server
+npm install
+npm run build
+cd ..
+
+# ========== 4. 同步到服务器 ==========
+log_info "========== 4. 同步到服务器 =========="
+
+# 同步前端
+log_info "同步前端..."
+ssh $SSH_OPTS $SERVER_USER@$SERVER_IP "mkdir -p $FRONTEND_PATH/build/h5"
+rsync -avz --delete \
+    -e "ssh $SSH_OPTS" \
+    --exclude='node_modules' \
+    --exclude='.git' \
+    my-uniapp-vue3/dist/build/h5/ \
+    $SERVER_USER@$SERVER_IP:$FRONTEND_PATH/build/h5/
+
+# 同步后端源码
+log_info "同步后端..."
+rsync -avz --delete \
+    -e "ssh $SSH_OPTS" \
+    --exclude='node_modules' \
+    --exclude='.git' \
+    --exclude='dist' \
+    --exclude='coverage' \
+    --exclude='*.log' \
+    server/ \
+    $SERVER_USER@$SERVER_IP:$SERVER_PATH/server/
+
+# ========== 5. 线上安装依赖并构建 ==========
+log_info "========== 5. 线上安装依赖并构建 =========="
+
+ssh $SSH_OPTS $SERVER_USER@$SERVER_IP << 'ENDSSH'
+    set -e
+    cd /data/ai/audio_codebuddy/server
+
+    echo "[INFO] 安装后端依赖..."
+    npm install
+
+    echo "[INFO] 生成 Prisma Client..."
+    npx prisma generate
+
+    echo "[INFO] 构建后端..."
+    npm run build
+
+    echo "[INFO] 重启 PM2 服务..."
+    pm2 delete server 2>/dev/null || true
+    SERVER_PORT=3100 pm2 start dist/app.js --name server
+    pm2 save
+
+    echo "[INFO] 检查服务状态..."
+    pm2 status
+ENDSSH
+
+# ========== 6. 完成 ==========
+log_info "========== 部署完成 =========="
+log_info "前端: https://book.rrbrr.com"
+log_info "后端: https://bookapi.rrbrr.com"
+
+# 验证服务
+log_info "验证服务..."
+curl -s --connect-timeout 5 http://bookapi.rrbrr.com/health && echo "" || log_warn "API 验证失败,请手动检查"

+ 123 - 0
deploy-remote.sh

@@ -0,0 +1,123 @@
+#!/bin/bash
+# 线上 pull 代码 + 编译部署脚本
+# 用法: bash deploy-remote.sh
+# 或者: ssh -p 22622 root@8.159.134.106 "cd /data/ai/audio_codebuddy && bash deploy-remote.sh"
+
+set -e
+
+# ========== 配置 ==========
+SERVER_PATH="/data/ai/audio_codebuddy"
+FRONTEND_PATH="/data/ai/frontend"
+BACKEND_PORT="3100"
+
+# ========== 颜色输出 ==========
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+log_info() { echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"; }
+log_error() { echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"; }
+
+# ========== 日志 ==========
+DEPLOY_LOG="/tmp/deploy-remote.log"
+exec > >(tee -a "$DEPLOY_LOG") 2>&1
+
+# ========== 0. 检查是否在服务器上运行 ==========
+if [[ ! -d "$SERVER_PATH/.git" ]]; then
+    log_error "不在正确的服务器目录: $SERVER_PATH"
+    exit 1
+fi
+
+# ========== 1. 拉取代码 ==========
+log_info "========== 1. 拉取代码 =========="
+cd "$SERVER_PATH"
+git fetch origin master
+git pull origin master
+log_info "当前版本: $(git log --oneline -1)"
+
+# ========== 2. 构建前端 ==========
+log_info "========== 2. 构建前端 =========="
+
+# 检查前端依赖
+if [[ ! -f "my-uniapp-vue3/package.json" ]]; then
+    log_error "前端 package.json 不存在,请先同步本地文件"
+    exit 1
+fi
+
+cd my-uniapp-vue3
+npm install
+npm run build:h5
+cd ..
+
+# 部署前端
+log_info "部署前端..."
+rm -rf "$FRONTEND_PATH/build/h5"
+mkdir -p "$FRONTEND_PATH/build/h5"
+cp -r my-uniapp-vue3/dist/build/h5/* "$FRONTEND_PATH/build/h5/"
+log_info "前端部署完成"
+
+# ========== 3. 构建后端 ==========
+log_info "========== 3. 构建后端 =========="
+cd server
+
+# 安装依赖
+npm install
+
+# 生成 Prisma Client
+npx prisma generate
+
+# 构建
+npm run build
+
+# 复制配置文件
+mkdir -p dist/config
+cp src/config/models.json dist/config/models.json 2>/dev/null || true
+
+cd ..
+
+# ========== 4. 重启服务 ==========
+log_info "========== 4. 重启服务 =========="
+
+# 检查 PM2 是否安装
+if command -v pm2 &> /dev/null; then
+    # 停止旧服务
+    pm2 delete server 2>/dev/null || true
+
+    # 启动新服务
+    SERVER_PORT=$BACKEND_PORT pm2 start server/dist/app.js --name server
+
+    # 保存
+    pm2 save
+
+    # 查看状态
+    pm2 status
+else
+    log_warn "PM2 未安装,跳过进程管理"
+fi
+
+# ========== 5. 验证 ==========
+log_info "========== 5. 验证服务 =========="
+sleep 2
+
+# 检查端口
+if ss -tlnp | grep -q ":$BACKEND_PORT"; then
+    log_info "端口 $BACKEND_PORT 已监听"
+else
+    log_warn "端口 $BACKEND_PORT 未监听"
+fi
+
+# 检查 API
+API_RESULT=$(curl -s --connect-timeout 5 http://127.0.0.1:$BACKEND_PORT/health || echo "FAILED")
+if [[ "$API_RESULT" != "FAILED" ]]; then
+    log_info "API 健康检查: $API_RESULT"
+else
+    log_warn "API 健康检查失败"
+fi
+
+# ========== 完成 ==========
+log_info "========== 部署完成 =========="
+log_info "前端: https://book.rrbrr.com"
+log_info "后端: https://bookapi.rrbrr.com"
+log_info "日志: $DEPLOY_LOG"

+ 0 - 10
server/src/modules/payment/payment.service.ts

@@ -342,15 +342,10 @@ async function generateWechatPayment(
   try {
   try {
     console.log('[WeChatPay] 开始创建 NATIVE 支付订单:', { orderNo, amount, subject });
     console.log('[WeChatPay] 开始创建 NATIVE 支付订单:', { orderNo, amount, subject });
 
 
-    // 设置支付截止时间(2小时)
-    const timeExpire = new Date(Date.now() + 2 * 60 * 60 * 1000);
-    const timeExpireStr = timeExpire.toISOString().replace(/\.\d{3}Z$/, '+08:00');
-
     // 使用 NATIVE 支付(扫码支付)
     // 使用 NATIVE 支付(扫码支付)
     const result: any = await wechat.transactions_native({
     const result: any = await wechat.transactions_native({
       description: subject,
       description: subject,
       out_trade_no: orderNo,
       out_trade_no: orderNo,
-      time_expire: timeExpireStr,
       amount: {
       amount: {
         total: Math.round(amount * 100), // 转换为分
         total: Math.round(amount * 100), // 转换为分
         currency: 'CNY',
         currency: 'CNY',
@@ -953,10 +948,6 @@ export async function generateWechatJsapiPayment(
   try {
   try {
     console.log('[WeChat JSAPI] 开始创建 JSAPI 支付订单:', { orderNo, amount, subject, openid });
     console.log('[WeChat JSAPI] 开始创建 JSAPI 支付订单:', { orderNo, amount, subject, openid });
 
 
-    // 设置支付截止时间(2小时后,微信默认7天但这里显式设置)
-    const timeExpire = new Date(Date.now() + 2 * 60 * 60 * 1000);
-    const timeExpireStr = timeExpire.toISOString().replace(/\.\d{3}Z$/, '+08:00');
-
     // SDK 的 transactions_jsapi 会自动:
     // SDK 的 transactions_jsapi 会自动:
     // 1. 添加 appid 和 mchid
     // 1. 添加 appid 和 mchid
     // 2. 调用 /v3/pay/transactions/jsapi
     // 2. 调用 /v3/pay/transactions/jsapi
@@ -965,7 +956,6 @@ export async function generateWechatJsapiPayment(
     const result: any = await wechat.transactions_jsapi({
     const result: any = await wechat.transactions_jsapi({
       description: subject,
       description: subject,
       out_trade_no: orderNo,
       out_trade_no: orderNo,
-      time_expire: timeExpireStr,
       amount: {
       amount: {
         total: Math.round(amount * 100), // 转换为分
         total: Math.round(amount * 100), // 转换为分
         currency: 'CNY',
         currency: 'CNY',