864 lines
24 KiB
Go
864 lines
24 KiB
Go
package handlers
|
|
|
|
import (
|
|
"awesomeProject/internal/common"
|
|
"awesomeProject/internal/models"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// UserOrderHandler 用户订单处理器
|
|
type UserOrderHandler struct{}
|
|
|
|
// CreatePurchaseOrder 创建买单
|
|
func (h *UserOrderHandler) CreatePurchaseOrder(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
var req struct {
|
|
ProductID uint `json:"product_id" binding:"required"`
|
|
ProductType uint8 `json:"product_type" binding:"required"` // 1一级商品,2二级商品
|
|
ProductName string `json:"product_name" binding:"required"`
|
|
ProductImages string `json:"product_images"`
|
|
UnitPrice float64 `json:"unit_price" binding:"required"`
|
|
Quantity int `json:"quantity" binding:"required"`
|
|
TotalAmount float64 `json:"total_amount" binding:"required"`
|
|
AddressID uint `json:"address_id" binding:"required"`
|
|
PaymentProofImage string `json:"payment_proof_image"` // 不再强制要求
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "请求参数错误"))
|
|
return
|
|
}
|
|
|
|
// 验证商品类型
|
|
if req.ProductType != 1 && req.ProductType != 2 {
|
|
c.JSON(http.StatusOK, common.Error(400, "商品类型无效"))
|
|
return
|
|
}
|
|
|
|
// 验证数量和金额
|
|
if req.Quantity <= 0 {
|
|
c.JSON(http.StatusOK, common.Error(400, "购买数量必须大于0"))
|
|
return
|
|
}
|
|
|
|
if req.TotalAmount != req.UnitPrice*float64(req.Quantity) {
|
|
c.JSON(http.StatusOK, common.Error(400, "订单金额计算错误"))
|
|
return
|
|
}
|
|
|
|
db := common.GetDB()
|
|
|
|
// 开启事务
|
|
tx := db.Begin()
|
|
|
|
// 验证收货地址是否属于当前用户
|
|
var address models.UserAddress
|
|
if err := tx.Where("id = ? AND user_id = ?", req.AddressID, user.ID).First(&address).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(404, "收货地址不存在"))
|
|
return
|
|
}
|
|
|
|
var sellerID *uint
|
|
//var productInfo interface{}
|
|
|
|
// 根据商品类型进行不同的处理
|
|
if req.ProductType == 1 { // 一级商品
|
|
var primaryProduct models.PrimaryProduct
|
|
if err := tx.First(&primaryProduct, req.ProductID).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询商品失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
// 检查商品状态和库存
|
|
if primaryProduct.Status != 1 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "商品已下架"))
|
|
return
|
|
}
|
|
|
|
if primaryProduct.StockQuantity < req.Quantity {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "库存不足"))
|
|
return
|
|
}
|
|
|
|
// 减少库存,增加销量
|
|
if err := tx.Model(&primaryProduct).Updates(map[string]interface{}{
|
|
"stock_quantity": primaryProduct.StockQuantity - req.Quantity,
|
|
"sales_count": primaryProduct.SalesCount + req.Quantity,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "更新商品库存失败"))
|
|
return
|
|
}
|
|
|
|
//productInfo = primaryProduct
|
|
|
|
} else { // 二级商品
|
|
var secondaryProduct models.SecondaryProduct
|
|
if err := tx.Preload("Seller").First(&secondaryProduct, req.ProductID).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "商品不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询商品失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
// 检查商品状态和库存
|
|
if secondaryProduct.Status != 1 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "商品已下架"))
|
|
return
|
|
}
|
|
|
|
if secondaryProduct.Quantity < req.Quantity {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "库存不足"))
|
|
return
|
|
}
|
|
|
|
// 检查是否是自己的商品
|
|
if secondaryProduct.SellerID == user.ID {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "不能购买自己的商品"))
|
|
return
|
|
}
|
|
var config models.SystemConfig
|
|
tx.Where("config_key=?", "limit_days").First(&config)
|
|
value, _ := strconv.Atoi(config.ConfigValue)
|
|
|
|
if value > 0 {
|
|
fiveDaysAgo := time.Now().AddDate(0, 0, -value)
|
|
var existingOrderCount int64
|
|
if err := tx.Model(&models.PurchaseOrder{}).Where(
|
|
"buyer_id = ? AND seller_id = ? AND product_type = 2 AND created_at > ? AND order_status != 3",
|
|
user.ID, secondaryProduct.SellerID, fiveDaysAgo,
|
|
).Count(&existingOrderCount).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "检查购买记录失败"))
|
|
return
|
|
}
|
|
|
|
if existingOrderCount > 0 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, fmt.Sprintf("%v天内只能向同一个卖家购买一次商品", value)))
|
|
return
|
|
}
|
|
}
|
|
|
|
// 减少库存,增加浏览量
|
|
if err := tx.Model(&secondaryProduct).Updates(map[string]interface{}{
|
|
"quantity": secondaryProduct.Quantity - req.Quantity,
|
|
"view_count": secondaryProduct.ViewCount + 1,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "更新商品库存失败"))
|
|
return
|
|
}
|
|
|
|
sellerID = &secondaryProduct.SellerID
|
|
//productInfo = secondaryProduct
|
|
}
|
|
|
|
// 生成订单编号
|
|
orderNo := fmt.Sprintf("PO%d%d", time.Now().Unix(), user.ID)
|
|
|
|
// 创建买单
|
|
orderStatus := 0 // 默认待付款
|
|
if req.PaymentProofImage != "" {
|
|
orderStatus = 1 // 如果有付款凭证,设为待确认
|
|
}
|
|
|
|
purchaseOrder := models.PurchaseOrder{
|
|
OrderNo: orderNo,
|
|
BuyerID: user.ID,
|
|
SellerID: sellerID,
|
|
ProductID: req.ProductID,
|
|
ProductType: req.ProductType,
|
|
ProductName: req.ProductName,
|
|
ProductImages: req.ProductImages,
|
|
UnitPrice: req.UnitPrice,
|
|
Quantity: req.Quantity,
|
|
TotalAmount: req.TotalAmount,
|
|
AddressID: &req.AddressID,
|
|
OrderStatus: uint8(orderStatus),
|
|
PaymentProofImage: req.PaymentProofImage,
|
|
Remark: req.Remark,
|
|
}
|
|
|
|
if err := tx.Create(&purchaseOrder).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "创建订单失败"))
|
|
return
|
|
}
|
|
|
|
//如果是二级商品,创建对应的卖单
|
|
if req.ProductType == 2 {
|
|
salesOrder := models.SalesOrder{
|
|
OrderNo: fmt.Sprintf("SO%d%d", time.Now().Unix(), *sellerID),
|
|
SellerID: *sellerID,
|
|
BuyerID: user.ID,
|
|
SecondaryProductID: req.ProductID,
|
|
ProductName: req.ProductName,
|
|
ProductImages: req.ProductImages,
|
|
SellingPrice: req.UnitPrice,
|
|
Quantity: req.Quantity,
|
|
TotalAmount: req.TotalAmount,
|
|
AddressID: &req.AddressID,
|
|
OrderStatus: 0, // 待付款
|
|
PaymentProofImage: req.PaymentProofImage,
|
|
PurchaseOrderID: purchaseOrder.ID,
|
|
}
|
|
|
|
if err := tx.Create(&salesOrder).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "创建卖单失败"))
|
|
return
|
|
}
|
|
}
|
|
|
|
// 提交事务
|
|
tx.Commit()
|
|
|
|
// 返回订单信息
|
|
result := map[string]interface{}{
|
|
"order_id": purchaseOrder.ID,
|
|
"order_no": purchaseOrder.OrderNo,
|
|
"status": "订单已提交,等待确认",
|
|
"message": "订单创建成功",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// GetPurchaseOrders 获取买单列表
|
|
func (h *UserOrderHandler) 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 > 50 {
|
|
pageSize = 10
|
|
}
|
|
order_id, _ := strconv.Atoi(c.DefaultQuery("order_id", "0"))
|
|
// 状态过滤
|
|
status := c.Query("status")
|
|
startDate := c.Query("start_date")
|
|
endDate := c.Query("end_date")
|
|
|
|
db := common.GetDB()
|
|
var orders []models.PurchaseOrder
|
|
var total int64
|
|
|
|
// 构建查询条件
|
|
query := db.Model(&models.PurchaseOrder{}).Where("buyer_id = ?", user.ID).
|
|
Preload("Address").Preload("Seller")
|
|
|
|
// 添加状态过滤
|
|
if status != "" && status != "all" {
|
|
switch status {
|
|
case "pending":
|
|
query = query.Where("order_status = 0")
|
|
case "confirming":
|
|
query = query.Where("order_status = 1")
|
|
case "completed":
|
|
query = query.Where("order_status = 2")
|
|
case "cancelled":
|
|
query = query.Where("order_status = 3")
|
|
}
|
|
}
|
|
|
|
// 添加日期过滤
|
|
if startDate != "" {
|
|
query = query.Where("created_at >= ?", startDate+" 00:00:00")
|
|
}
|
|
if endDate != "" {
|
|
query = query.Where("created_at <= ?", endDate+" 23:59:59")
|
|
}
|
|
if order_id > 0 {
|
|
query = query.Where("id = ?", order_id)
|
|
}
|
|
// 获取总数
|
|
query.Count(&total)
|
|
|
|
// 分页查询
|
|
offset := (page - 1) * pageSize
|
|
err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&orders).Error
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询订单列表失败"))
|
|
return
|
|
}
|
|
|
|
// 计算总金额
|
|
var totalAmount float64
|
|
db.Model(&models.PurchaseOrder{}).Where("buyer_id = ? AND order_status = 2", user.ID).Select("COALESCE(SUM(total_amount), 0)").Scan(&totalAmount)
|
|
|
|
// 构建返回数据
|
|
result := map[string]interface{}{
|
|
"list": orders,
|
|
"total": total,
|
|
"page": page,
|
|
"page_size": pageSize,
|
|
"total_amount": totalAmount,
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// GetSalesOrders 获取卖单列表
|
|
func (h *UserOrderHandler) 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 > 50 {
|
|
pageSize = 10
|
|
}
|
|
|
|
// 状态过滤
|
|
status := c.Query("status")
|
|
startDate := c.Query("start_date")
|
|
endDate := c.Query("end_date")
|
|
|
|
db := common.GetDB()
|
|
var orders []models.SalesOrder
|
|
var total int64
|
|
|
|
// 构建查询条件
|
|
query := db.Model(&models.SalesOrder{}).Where("seller_id = ?", user.ID).Preload("Buyer").Preload("Address")
|
|
|
|
// 添加状态过滤
|
|
if status != "" && status != "all" {
|
|
switch status {
|
|
case "pending":
|
|
query = query.Where("order_status = 0")
|
|
case "confirming":
|
|
query = query.Where("order_status = 1")
|
|
case "completed":
|
|
query = query.Where("order_status = 2")
|
|
case "cancelled":
|
|
query = query.Where("order_status = 3")
|
|
}
|
|
}
|
|
|
|
// 添加日期过滤
|
|
if startDate != "" {
|
|
query = query.Where("created_at >= ?", startDate+" 00:00:00")
|
|
}
|
|
if endDate != "" {
|
|
query = query.Where("created_at <= ?", endDate+" 23:59:59")
|
|
}
|
|
|
|
// 获取总数
|
|
query.Count(&total)
|
|
|
|
// 分页查询
|
|
offset := (page - 1) * pageSize
|
|
err := query.Order("created_at DESC").Offset(offset).Limit(pageSize).Find(&orders).Error
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询卖单列表失败"))
|
|
return
|
|
}
|
|
|
|
// 计算总金额
|
|
var totalAmount float64
|
|
db.Model(&models.SalesOrder{}).Where("seller_id = ? AND order_status = 2", user.ID).Select("COALESCE(SUM(total_amount), 0)").Scan(&totalAmount)
|
|
|
|
// 构建返回数据
|
|
result := map[string]interface{}{
|
|
"list": orders,
|
|
"total": total,
|
|
"page": page,
|
|
"page_size": pageSize,
|
|
"total_amount": totalAmount,
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// GetOrderStats 获取订单统计信息(待付款和待确认数量)
|
|
func (h *UserOrderHandler) GetOrderStats(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
db := common.GetDB()
|
|
stats := make(map[string]interface{})
|
|
|
|
// 买单统计
|
|
var purchasePendingCount int64 // 待付款
|
|
var purchaseConfirmingCount int64 // 待确认
|
|
db.Model(&models.PurchaseOrder{}).Where("buyer_id = ? AND order_status = ?", user.ID, 0).Count(&purchasePendingCount)
|
|
db.Model(&models.PurchaseOrder{}).Where("buyer_id = ? AND order_status = ?", user.ID, 1).Count(&purchaseConfirmingCount)
|
|
|
|
// 卖单统计
|
|
var salesPendingCount int64 // 待付款
|
|
var salesConfirmingCount int64 // 待确认
|
|
db.Model(&models.SalesOrder{}).Where("seller_id = ? AND order_status = ?", user.ID, 0).Count(&salesPendingCount)
|
|
db.Model(&models.SalesOrder{}).Where("seller_id = ? AND order_status = ?", user.ID, 1).Count(&salesConfirmingCount)
|
|
|
|
stats["purchase_pending_count"] = purchasePendingCount
|
|
stats["purchase_confirming_count"] = purchaseConfirmingCount
|
|
stats["sales_pending_count"] = salesPendingCount
|
|
stats["sales_confirming_count"] = salesConfirmingCount
|
|
|
|
c.JSON(http.StatusOK, common.Success(stats))
|
|
}
|
|
|
|
// ConfirmPurchaseOrder 确认买单(买家确认收货)
|
|
func (h *UserOrderHandler) ConfirmPurchaseOrder(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
|
|
return
|
|
}
|
|
|
|
db := common.GetDB()
|
|
tx := db.Begin()
|
|
|
|
// 买家确认买单(确认收货)
|
|
var order models.PurchaseOrder
|
|
if err := tx.Where("id = ? AND buyer_id = ?", orderID, user.ID).First(&order).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询订单失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
if order.OrderStatus != 1 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "订单状态不允许确认"))
|
|
return
|
|
}
|
|
|
|
// 更新订单状态为已完成
|
|
now := time.Now()
|
|
if err := tx.Model(&order).Updates(map[string]interface{}{
|
|
"order_status": 2,
|
|
"confirm_time": &now,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "确认订单失败"))
|
|
return
|
|
}
|
|
|
|
// 商品入库
|
|
if err := h.addToWarehouse(tx, user.ID, &order); err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "商品入库失败"))
|
|
return
|
|
}
|
|
|
|
tx.Commit()
|
|
|
|
result := map[string]interface{}{
|
|
"message": "订单确认成功,商品已入库",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// ConfirmSalesOrder 确认卖单(卖家确认发货)
|
|
func (h *UserOrderHandler) ConfirmSalesOrder(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
|
|
return
|
|
}
|
|
|
|
// 卖家确认卖单
|
|
var order models.SalesOrder
|
|
tx := common.GetDB().Begin()
|
|
if err := tx.Where("id = ? AND seller_id = ?", orderID, user.ID).First(&order).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询订单失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
if order.OrderStatus != 1 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "订单状态不允许确认"))
|
|
return
|
|
}
|
|
|
|
// 更新卖单状态为已完成
|
|
now := time.Now()
|
|
if err := tx.Model(&order).Updates(models.SalesOrder{
|
|
OrderStatus: 2,
|
|
CompleteTime: &now,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "确认订单失败"))
|
|
return
|
|
}
|
|
|
|
// 同时更新对应的买单状态
|
|
if err := tx.Model(&models.PurchaseOrder{}).Where(
|
|
"id=?",
|
|
order.PurchaseOrderID,
|
|
).Updates(models.PurchaseOrder{
|
|
OrderStatus: 2,
|
|
ConfirmTime: &now,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "更新买单状态失败"))
|
|
return
|
|
}
|
|
|
|
var config models.SystemConfig
|
|
tx.Where("config_key=?", "warehouse_price_rate").First(&config)
|
|
vaule, _ := strconv.Atoi(config.ConfigValue)
|
|
newRecord := models.ScoreRecord{
|
|
UserID: user.ID,
|
|
Note: "系统策略",
|
|
ChangeNumber: -vaule,
|
|
}
|
|
|
|
if err := tx.Create(&newRecord).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "创建积分记录失败"))
|
|
return
|
|
}
|
|
|
|
// 更新用户积分
|
|
newPoints := user.CurrentPoints + newRecord.ChangeNumber
|
|
if newPoints < 0 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "用户积分不足"))
|
|
return
|
|
}
|
|
|
|
if err := tx.Model(&user).Update("current_points", newPoints).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "更新用户积分失败"))
|
|
return
|
|
}
|
|
|
|
tx.Commit()
|
|
|
|
var purcharseOrder models.PurchaseOrder
|
|
db := common.GetDB()
|
|
db.Where("id=?", order.PurchaseOrderID).First(&purcharseOrder)
|
|
err = h.addToWarehouse(db, order.BuyerID, &purcharseOrder)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "添加用户仓库失败"))
|
|
}
|
|
result := map[string]interface{}{
|
|
"message": "订单确认成功",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// addToWarehouse 添加商品到买家仓库
|
|
func (h *UserOrderHandler) addToWarehouse(tx *gorm.DB, buyerID uint, order *models.PurchaseOrder) error {
|
|
|
|
fmt.Println("order::", order)
|
|
// 检查该订单是否已经入库(防止重复入库)
|
|
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 config models.SystemConfig
|
|
tx.Where("config_key=?", "warehouse_price_rate").First(&config)
|
|
value, _ := strconv.Atoi(config.ConfigValue)
|
|
// 计算入库价格(根据系统配置增值)
|
|
warehousePrice := order.UnitPrice + float64(value)
|
|
|
|
// 检查仓库中是否已有相同商品(不同订单的相同商品)
|
|
var existingWarehouse models.UserWarehouse
|
|
//err = tx.Where("user_id = ? AND product_id = ? AND product_type = ?",
|
|
// buyerID, order.ProductID, order.ProductType).First(&existingWarehouse).Error
|
|
|
|
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
|
|
}
|
|
|
|
}
|
|
|
|
// UploadPaymentProof 上传付款凭证
|
|
func (h *UserOrderHandler) UploadPaymentProof(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
|
|
return
|
|
}
|
|
|
|
var req struct {
|
|
PaymentProofImage string `json:"payment_proof_image" binding:"required"`
|
|
ProductType uint `json:"product_type" binding:"required"`
|
|
}
|
|
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "请求参数错误"))
|
|
return
|
|
}
|
|
|
|
db := common.GetDB()
|
|
tx := db.Begin()
|
|
|
|
// 查询订单
|
|
var order models.PurchaseOrder
|
|
if err := tx.Where("id = ? AND buyer_id = ?", orderID, user.ID).First(&order).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询订单失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
// 检查订单状态
|
|
if order.OrderStatus != 0 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "订单状态不允许上传付款凭证"))
|
|
return
|
|
}
|
|
|
|
// 更新订单状态为待确认,并保存付款凭证
|
|
if err := tx.Model(&order).Updates(map[string]interface{}{
|
|
"payment_proof_image": req.PaymentProofImage,
|
|
"order_status": 1, // 待确认
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "更新订单失败"))
|
|
return
|
|
}
|
|
|
|
var saleOrder models.SalesOrder
|
|
if req.ProductType == 2 {
|
|
|
|
if err := tx.Where("purchase_order_id = ?", order.ID).First(&saleOrder).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(200, common.Error(400, "查找不到有效订单"))
|
|
}
|
|
|
|
// 再更新,这里可以使用 Model 指定要更新的对象
|
|
// 注意:这仍然会基于 saleOrder 的主键 ID 更新,但因为我们刚查出来,所以是安全的。
|
|
// 但更清晰的方式是直接用 Where。
|
|
|
|
// 更好的方式是:直接基于原始条件更新
|
|
if err := tx.Where("purchase_order_id = ?", order.ID).Updates(models.SalesOrder{
|
|
OrderStatus: 1,
|
|
PaymentProofImage: req.PaymentProofImage,
|
|
}).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(200, common.Error(400, "更新错误"))
|
|
}
|
|
}
|
|
|
|
tx.Commit()
|
|
|
|
result := map[string]interface{}{
|
|
"message": "付款凭证上传成功,订单已提交等待确认",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// CancelOrder 取消订单
|
|
func (h *UserOrderHandler) CancelOrder(c *gin.Context) {
|
|
currentUser, _ := c.Get("current_user")
|
|
user := currentUser.(models.User)
|
|
|
|
orderID, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
|
if err != nil {
|
|
c.JSON(http.StatusOK, common.Error(400, "订单ID无效"))
|
|
return
|
|
}
|
|
|
|
db := common.GetDB()
|
|
tx := db.Begin()
|
|
|
|
// 查询订单
|
|
var order models.PurchaseOrder
|
|
if err := tx.Where("id = ? AND buyer_id = ?", orderID, user.ID).First(&order).Error; err != nil {
|
|
tx.Rollback()
|
|
if err == gorm.ErrRecordNotFound {
|
|
c.JSON(http.StatusOK, common.Error(404, "订单不存在"))
|
|
} else {
|
|
c.JSON(http.StatusOK, common.Error(500, "查询订单失败"))
|
|
}
|
|
return
|
|
}
|
|
|
|
// 检查订单状态(只有待付款和待确认的订单可以取消)
|
|
if order.OrderStatus != 0 && order.OrderStatus != 1 {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(400, "订单状态不允许取消"))
|
|
return
|
|
}
|
|
|
|
// 更新订单状态为已取消
|
|
if err := tx.Model(&order).Update("order_status", 3).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "取消订单失败"))
|
|
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()
|
|
c.JSON(http.StatusOK, common.Error(500, "恢复库存失败"))
|
|
return
|
|
}
|
|
} else { // 二级商品
|
|
if err := tx.Model(&models.SecondaryProduct{}).Where("id = ?", order.ProductID).
|
|
Update("quantity", gorm.Expr("quantity + ?", order.Quantity)).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusOK, common.Error(500, "恢复库存失败"))
|
|
return
|
|
}
|
|
}
|
|
|
|
tx.Commit()
|
|
|
|
result := map[string]interface{}{
|
|
"message": "订单已取消",
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(result))
|
|
}
|
|
|
|
// GetPurchaseOrderDetail 获取买单详情
|
|
func (h *UserOrderHandler) GetPurchaseOrderDetail(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().Where("buyer_id = ?", user.ID).
|
|
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
|
|
}
|
|
adminID := uint(1)
|
|
if order.ProductType == 1 {
|
|
if order.SellerID == nil {
|
|
order.SellerID = &adminID
|
|
var seller models.User
|
|
|
|
common.GetDB().Where("id=?", order.SellerID).First(&seller)
|
|
order.Seller = &seller
|
|
}
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(order))
|
|
}
|
|
|
|
// GetSalesOrderDetail 获取卖单详情
|
|
func (h *UserOrderHandler) GetSalesOrderDetail(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().Where("seller_id = ?", user.ID).
|
|
Preload("Seller").
|
|
Preload("Buyer").
|
|
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
|
|
}
|
|
|
|
c.JSON(http.StatusOK, common.Success(order))
|
|
}
|