76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"soul-api/internal/database"
|
|
"soul-api/internal/model"
|
|
"soul-api/internal/wechat"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// CronSyncOrders GET/POST /api/cron/sync-orders
|
|
// 对账:查询 status=created 的订单,向微信查询实际状态,若已支付则补齐更新(防漏单)
|
|
func CronSyncOrders(c *gin.Context) {
|
|
db := database.DB()
|
|
var createdOrders []model.Order
|
|
// 只处理最近 24 小时内创建的未支付订单
|
|
cutoff := time.Now().Add(-24 * time.Hour)
|
|
if err := db.Where("status = ? AND created_at > ?", "created", cutoff).Find(&createdOrders).Error; err != nil {
|
|
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
|
|
return
|
|
}
|
|
|
|
synced := 0
|
|
ctx := context.Background()
|
|
for _, o := range createdOrders {
|
|
tradeState, transactionID, totalFee, err := wechat.QueryOrderByOutTradeNo(ctx, o.OrderSN)
|
|
if err != nil {
|
|
fmt.Printf("[SyncOrders] 查询订单 %s 失败: %v\n", o.OrderSN, err)
|
|
continue
|
|
}
|
|
if tradeState != "SUCCESS" {
|
|
continue
|
|
}
|
|
// 微信已支付,本地未更新 → 补齐
|
|
totalAmount := float64(totalFee) / 100
|
|
now := time.Now()
|
|
if err := db.Model(&o).Updates(map[string]interface{}{
|
|
"status": "paid",
|
|
"transaction_id": transactionID,
|
|
"pay_time": now,
|
|
"updated_at": now,
|
|
}).Error; err != nil {
|
|
fmt.Printf("[SyncOrders] 更新订单 %s 失败: %v\n", o.OrderSN, err)
|
|
continue
|
|
}
|
|
synced++
|
|
fmt.Printf("[SyncOrders] 补齐漏单: %s, amount=%.2f\n", o.OrderSN, totalAmount)
|
|
|
|
// 同步后续逻辑(全书、分销等)
|
|
pt := "fullbook"
|
|
if o.ProductType != "" {
|
|
pt = o.ProductType
|
|
}
|
|
if pt == "fullbook" {
|
|
db.Model(&model.User{}).Where("id = ?", o.UserID).Update("has_full_book", true)
|
|
}
|
|
processReferralCommission(db, o.UserID, totalAmount, o.OrderSN, &o)
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"success": true,
|
|
"synced": synced,
|
|
"total": len(createdOrders),
|
|
})
|
|
}
|
|
|
|
// CronUnbindExpired GET/POST /api/cron/unbind-expired
|
|
func CronUnbindExpired(c *gin.Context) {
|
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
|
}
|