This commit is contained in:
solosw
2026-01-05 14:11:34 +08:00
parent 35ef825371
commit 99b11b04e4
658 changed files with 99266 additions and 0 deletions
+631
View File
@@ -0,0 +1,631 @@
package handlers
import (
"awesomeProject/internal/common"
"awesomeProject/internal/models"
"fmt"
"strconv"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"net/http"
)
// AdminOrderHandler 管理端订单处理器
type AdminOrderHandler struct{}
// GetPurchaseOrders 获取买单列表
func (h *AdminOrderHandler) GetPurchaseOrders(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 分页参数
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
// 搜索参数
orderNo := c.Query("order_no")
orderStatus := c.Query("order_status")
productType := c.Query("product_type")
sellerName := c.Query("seller_name")
buyerName := c.Query("buyer_name")
db := common.GetDB()
var orders []models.PurchaseOrder
var total int64
// 构建查询条件
query := db.Model(&models.PurchaseOrder{}).Preload("Buyer").Preload("Seller").Preload("Address")
// 如果是代理商,只能查看自己邀请的用户的订单
if user.SystemRole == 1 {
// 子查询:获取代理商邀请的用户ID列表
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
query = query.Where("buyer_id IN (?)", subQuery)
}
// 添加搜索条件
if orderNo != "" {
query = query.Where("order_no LIKE ?", "%"+orderNo+"%")
}
if orderStatus != "" {
query = query.Where("order_status = ?", orderStatus)
}
if productType != "" {
query = query.Where("product_type = ?", productType)
}
if sellerName != "" {
query = query.Joins("LEFT JOIN users AS sellers ON purchase_orders.seller_id = sellers.id").
Where("sellers.real_name LIKE ? OR sellers.phone LIKE ?", "%"+sellerName+"%", "%"+sellerName+"%")
}
if buyerName != "" {
query = query.Joins("LEFT JOIN users AS buyers ON purchase_orders.buyer_id = buyers.id").
Where("buyers.real_name LIKE ? OR buyers.phone LIKE ?", "%"+buyerName+"%", "%"+buyerName+"%")
}
// 获取总数
query.Count(&total)
// 分页查询
offset := (page - 1) * pageSize
err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&orders).Error
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "查询买单列表失败"))
return
}
// 构建返回数据
result := map[string]interface{}{
"list": orders,
"total": total,
"page": page,
"page_size": pageSize,
}
c.JSON(http.StatusOK, common.Success(result))
}
// GetSalesOrders 获取卖单列表
func (h *AdminOrderHandler) GetSalesOrders(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 分页参数
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 10
}
// 搜索参数
orderNo := c.Query("order_no")
orderStatus := c.Query("order_status")
sellerName := c.Query("seller_name")
buyerName := c.Query("buyer_name")
db := common.GetDB()
var orders []models.SalesOrder
var total int64
// 构建查询条件
query := db.Model(&models.SalesOrder{}).Preload("Seller").Preload("Buyer").Preload("SecondaryProduct").Preload("Address")
// 如果是代理商,只能查看自己邀请的用户相关的订单
if user.SystemRole == 1 {
// 子查询:获取代理商邀请的用户ID列表
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
query = query.Where("buyer_id IN (?) OR seller_id IN (?)", subQuery, subQuery)
}
// 添加搜索条件
if orderNo != "" {
query = query.Where("order_no LIKE ?", "%"+orderNo+"%")
}
if orderStatus != "" {
query = query.Where("order_status = ?", orderStatus)
}
if sellerName != "" {
query = query.Joins("LEFT JOIN users AS sellers ON sales_orders.seller_id = sellers.id").
Where("sellers.real_name LIKE ? OR sellers.phone LIKE ?", "%"+sellerName+"%", "%"+sellerName+"%")
}
if buyerName != "" {
query = query.Joins("LEFT JOIN users AS buyers ON sales_orders.buyer_id = buyers.id").
Where("buyers.real_name LIKE ? OR buyers.phone LIKE ?", "%"+buyerName+"%", "%"+buyerName+"%")
}
// 获取总数
query.Count(&total)
// 分页查询
offset := (page - 1) * pageSize
err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&orders).Error
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "查询卖单列表失败"))
return
}
// 构建返回数据
result := map[string]interface{}{
"list": orders,
"total": total,
"page": page,
"page_size": pageSize,
}
c.JSON(http.StatusOK, common.Success(result))
}
// GetPurchaseOrder 获取单个买单详情
func (h *AdminOrderHandler) GetPurchaseOrder(c *gin.Context) {
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
return
}
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
var order models.PurchaseOrder
query := common.GetDB().Preload("Buyer").Preload("Seller").Preload("Address")
err = query.First(&order, uint(orderID)).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
} else {
c.JSON(http.StatusOK, common.Error(500, "查询订单详情失败"))
}
return
}
// 如果是代理商,检查权限
if user.SystemRole == 1 {
// 检查买家是否为代理商邀请的用户
if order.Buyer.ReferrerIdentityCode != user.IdentityCode {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
}
c.JSON(http.StatusOK, common.Success(order))
}
// GetSalesOrder 获取单个卖单详情
func (h *AdminOrderHandler) GetSalesOrder(c *gin.Context) {
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
return
}
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
var order models.SalesOrder
query := common.GetDB().Preload("Seller").Preload("Buyer").Preload("SecondaryProduct").Preload("Address")
err = query.First(&order, uint(orderID)).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
} else {
c.JSON(http.StatusOK, common.Error(500, "查询订单详情失败"))
}
return
}
// 如果是代理商,检查权限
if user.SystemRole == 1 {
// 检查买家或卖家是否为代理商邀请的用户
if order.Buyer.ReferrerIdentityCode != user.IdentityCode && order.Seller.ReferrerIdentityCode != user.IdentityCode {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
}
c.JSON(http.StatusOK, common.Success(order))
}
// UpdatePurchaseOrderStatus 更新买单状态(仅管理员)
func (h *AdminOrderHandler) UpdatePurchaseOrderStatus(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 只有管理员可以更新订单状态
if user.SystemRole != 0 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
return
}
var updateData struct {
OrderStatus uint8 `json:"order_status" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&updateData); err != nil {
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
return
}
db := common.GetDB()
tx := db.Begin()
// 检查订单是否存在
var order models.PurchaseOrder
if err := tx.First(&order, uint(orderID)).Error; err != nil {
tx.Rollback()
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
return
}
// 更新订单状态
updateFields := map[string]interface{}{
"order_status": updateData.OrderStatus,
"remark": updateData.Remark,
}
// 如果状态为已完成,设置确认时间并将商品入库
if updateData.OrderStatus == 2 {
now := time.Now()
updateFields["confirm_time"] = &now
// 商品入库到买家仓库
if err := h.addToWarehouse(tx, order.BuyerID, &order); err != nil {
tx.Rollback()
c.JSON(http.StatusOK, common.Error(500, "商品入库失败"))
return
}
}
if err := tx.Model(&order).Updates(updateFields).Error; err != nil {
tx.Rollback()
c.JSON(http.StatusOK, common.Error(500, "更新订单状态失败"))
return
}
tx.Commit()
result := map[string]interface{}{
"message": "订单状态更新成功",
}
if updateData.OrderStatus == 2 {
result["message"] = "订单确认成功,商品已入库"
}
c.JSON(http.StatusOK, common.Success(result))
}
// UpdateSalesOrderStatus 更新卖单状态(仅管理员)
func (h *AdminOrderHandler) UpdateSalesOrderStatus(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
// 只有管理员可以更新订单状态
if user.SystemRole != 0 {
c.JSON(http.StatusOK, common.Error(403, "权限不足"))
return
}
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
if err != nil {
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
return
}
var updateData struct {
OrderStatus uint8 `json:"order_status" binding:"required"`
Remark string `json:"remark"`
}
if err := c.ShouldBindJSON(&updateData); err != nil {
c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error()))
return
}
// 检查订单是否存在
var order models.SalesOrder
if err := common.GetDB().First(&order, uint(orderID)).Error; err != nil {
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
return
}
// 更新订单状态
updateFields := map[string]interface{}{
"order_status": updateData.OrderStatus,
"remark": updateData.Remark,
}
// 如果状态为确认完成,设置完成时间
if updateData.OrderStatus == 2 {
updateFields["complete_time"] = time.Now()
db := common.GetDB()
var purcharseOrder models.PurchaseOrder
db.Where("id=?", order.PurchaseOrderID).First(&purcharseOrder)
err := h.addToWarehouse(db, purcharseOrder.BuyerID, &purcharseOrder)
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "确认失败"))
}
}
if updateData.OrderStatus == 3 {
canel(order.PurchaseOrderID, order.BuyerID)
}
if err := common.GetDB().Model(&order).Updates(updateFields).Error; err != nil {
c.JSON(http.StatusOK, common.Error(500, "更新订单状态失败"))
return
}
c.JSON(http.StatusOK, common.Success(nil))
}
// GetOrderStats 获取订单统计信息
func (h *AdminOrderHandler) GetOrderStats(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
db := common.GetDB()
stats := make(map[string]interface{})
// 买单统计
purchaseQuery := db.Model(&models.PurchaseOrder{}).Where("order_status = ?", 2)
if user.SystemRole == 1 {
// 代理商只统计自己邀请的用户的订单
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
purchaseQuery = purchaseQuery.Where("buyer_id IN (?)", subQuery)
}
var totalPurchaseOrders int64
var totalPurchaseAmount float64
purchaseQuery.Count(&totalPurchaseOrders)
purchaseQuery.Select("COALESCE(SUM(total_amount), 0)").Scan(&totalPurchaseAmount)
stats["total_purchase_orders"] = totalPurchaseOrders
stats["total_purchase_amount"] = totalPurchaseAmount
// 卖单统计
salesQuery := db.Model(&models.SalesOrder{})
if user.SystemRole == 1 {
// 代理商只统计自己邀请的用户相关的订单
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
salesQuery = salesQuery.Where("buyer_id IN (?) OR seller_id IN (?)", subQuery, subQuery)
}
var totalSalesOrders int64
var totalSalesAmount float64
salesQuery.Count(&totalSalesOrders)
salesQuery.Select("COALESCE(SUM(total_amount), 0)").Scan(&totalSalesAmount)
stats["total_sales_orders"] = totalSalesOrders
stats["total_sales_amount"] = totalSalesAmount
// 今日订单统计
todayPurchaseQuery := purchaseQuery
if user.SystemRole == 1 {
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
todayPurchaseQuery = todayPurchaseQuery.Where("buyer_id IN (?)", subQuery)
}
var todayPurchaseOrders int64
todayPurchaseQuery.Where("DATE(created_at) = CURDATE()").Count(&todayPurchaseOrders)
todaySalesQuery := salesQuery
if user.SystemRole == 1 {
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
todaySalesQuery = todaySalesQuery.Where("buyer_id IN (?) OR seller_id IN (?)", subQuery, subQuery)
}
var todaySalesOrders int64
todaySalesQuery.Where("DATE(created_at) = CURDATE()").Count(&todaySalesOrders)
stats["today_purchase_orders"] = todayPurchaseOrders
stats["today_sales_orders"] = todaySalesOrders
c.JSON(http.StatusOK, common.Success(stats))
}
func canel(OrderID, UserID uint) {
db := common.GetDB()
tx := db.Begin()
// 查询订单
var order models.PurchaseOrder
if err := tx.Where("id = ? AND buyer_id = ?", OrderID, UserID).First(&order).Error; err != nil {
tx.Rollback()
return
}
// 检查订单状态(只有待付款和待确认的订单可以取消)
if order.OrderStatus != 0 && order.OrderStatus != 1 {
tx.Rollback()
return
}
// 更新订单状态为已取消
if err := tx.Model(&order).Update("order_status", 3).Error; err != nil {
tx.Rollback()
return
}
// 恢复商品库存
if order.ProductType == 1 { // 一级商品
if err := tx.Model(&models.PrimaryProduct{}).Where("id = ?", order.ProductID).
Update("stock_quantity", gorm.Expr("stock_quantity + ?", order.Quantity)).Error; err != nil {
tx.Rollback()
return
}
} else { // 二级商品
if err := tx.Model(&models.SecondaryProduct{}).Where("id = ?", order.ProductID).
Update("quantity", gorm.Expr("quantity + ?", order.Quantity)).Error; err != nil {
tx.Rollback()
return
}
}
tx.Commit()
}
// addToWarehouse 添加商品到买家仓库
func (h *AdminOrderHandler) addToWarehouse(tx *gorm.DB, buyerID uint, order *models.PurchaseOrder) error {
var config models.SystemConfig
// 计算入库价格(根据系统配置增值)
// 检查该订单是否已经入库(防止重复入库)
var existingByOrder models.UserWarehouse
err := tx.Where("user_id = ? AND source_order_id = ? and product_type=? and product_id=?",
buyerID, order.ID, order.ProductType, order.ProductID).First(&existingByOrder).Error
if err == nil {
// 该订单已经入库,直接返回
return nil
} else if err != gorm.ErrRecordNotFound {
// 查询出错
return err
}
// 检查仓库中是否已有相同商品(不同订单的相同商品)
var existingWarehouse models.UserWarehouse
//err = tx.Where("user_id = ? AND product_id = ? AND product_type = ?",
// buyerID, order.ProductID, order.ProductType).First(&existingWarehouse).Error
_ = tx.Where("config_key= ?", "warehouse_price_rate").First(&config).Error
value, _ := strconv.ParseFloat(config.ConfigValue, 64)
warehousePrice := order.UnitPrice + value
if err == gorm.ErrRecordNotFound {
// 创建新的仓库记录
warehouse := models.UserWarehouse{
UserID: buyerID,
ProductID: order.ProductID,
ProductType: order.ProductType,
ProductName: order.ProductName,
ProductImages: order.ProductImages,
PurchasePrice: order.UnitPrice,
WarehousePrice: warehousePrice,
Quantity: order.Quantity,
SourceOrderID: &order.ID,
Status: 1, // 库存中
}
return tx.Create(&warehouse).Error
} else if err != nil {
return err
} else {
// 更新现有仓库记录的数量(累加不同订单的相同商品)
return tx.Model(&existingWarehouse).Update("quantity", existingWarehouse.Quantity+order.Quantity).Error
}
}
func (h *AdminOrderHandler) GetOrderTrend(c *gin.Context) {
db := common.GetDB()
type DailyStats struct {
Date string `json:"date"`
Count int `json:"count"`
}
result := make([]DailyStats, 0, 7)
now := time.Now()
for i := 6; i >= 0; i-- {
// 当天 00:00:00
startOfDay := time.Date(now.Year(), now.Month(), now.Day()-i, 0, 0, 0, 0, now.Location())
// 次日 00:00:00
endOfDay := startOfDay.AddDate(0, 0, 1)
// 格式化显示用的 "01-02"
displayDateStr := startOfDay.Format("01-02")
var count int64
db.Model(&models.PurchaseOrder{}).
Where("created_at >= ? AND created_at < ?", startOfDay, endOfDay).
Count(&count)
result = append(result, DailyStats{
Date: displayDateStr,
Count: int(count),
})
}
c.JSON(http.StatusOK, common.Success(map[string]interface{}{
"trend": result,
}))
}
// GetRecentActivities 获取最近活动
func (h *AdminOrderHandler) GetRecentActivities(c *gin.Context) {
currentUser, _ := c.Get("current_user")
user := currentUser.(models.User)
db := common.GetDB()
// 准备返回数据结构
type Activity struct {
ID uint `json:"id"`
Description string `json:"description"`
Time time.Time `json:"time"`
}
var activities []Activity
// 获取最近的订单活动(最多10条)
var recentOrders []models.PurchaseOrder
orderQuery := db.Model(&models.PurchaseOrder{}).Preload("Buyer")
if user.SystemRole == 1 {
// 代理商只能看到自己邀请的用户的活动
subQuery := db.Model(&models.User{}).Select("id").Where("referrer_identity_code = ?", user.IdentityCode)
orderQuery = orderQuery.Where("buyer_id IN (?)", subQuery)
}
err := orderQuery.Order("created_at DESC").Limit(10).Find(&recentOrders).Error
if err != nil {
c.JSON(http.StatusOK, common.Error(500, "获取最近活动失败"))
return
}
// 将订单转换为活动
for _, order := range recentOrders {
var description string
switch order.OrderStatus {
case 0:
description = fmt.Sprintf("用户 %s 创建了新订单 %s", order.Buyer.Phone, order.OrderNo)
case 1:
description = fmt.Sprintf("用户 %s 提交了订单 %s 的付款凭证", order.Buyer.Phone, order.OrderNo)
case 2:
description = fmt.Sprintf("订单 %s 已完成", order.OrderNo)
case 3:
description = fmt.Sprintf("订单 %s 已取消", order.OrderNo)
}
activities = append(activities, Activity{
ID: order.ID,
Description: description,
Time: order.CreatedAt,
})
}
c.JSON(http.StatusOK, common.Success(map[string]interface{}{
"activities": activities,
}))
}