cockpit-source/backend/internal/api/orders.go
2026-04-02 14:12:43 +08:00

205 lines
5.7 KiB
Go

package api
import (
"net/http"
"strconv"
"strings"
"time"
"cockpit/internal/domain"
"cockpit/internal/middleware"
"github.com/gin-gonic/gin"
"github.com/shopspring/decimal"
)
type orderReq struct {
OrderNo string `json:"orderNo" binding:"required"`
OrderDate string `json:"orderDate" binding:"required"` // YYYY-MM-DD
ShipDate string `json:"shipDate"` // optional
AmountA string `json:"amountA" binding:"required"`
AmountB string `json:"amountB" binding:"required"`
CustomerID uint64 `json:"customerId" binding:"required"`
StatusID uint64 `json:"statusId" binding:"required"`
Remark string `json:"remark"`
}
func (h *Handler) OrderList(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
size, _ := strconv.Atoi(c.DefaultQuery("size", "20"))
if page < 1 {
page = 1
}
if size < 1 || size > 200 {
size = 20
}
q := h.db.Model(&domain.Order{})
if v := strings.TrimSpace(c.Query("dateFrom")); v != "" {
if t, err := time.Parse("2006-01-02", v); err == nil {
q = q.Where("order_date >= ?", t)
}
}
if v := strings.TrimSpace(c.Query("dateTo")); v != "" {
if t, err := time.Parse("2006-01-02", v); err == nil {
q = q.Where("order_date <= ?", t)
}
}
if v := strings.TrimSpace(c.Query("customerId")); v != "" {
if id, err := strconv.ParseUint(v, 10, 64); err == nil {
q = q.Where("customer_id = ?", id)
}
}
if v := strings.TrimSpace(c.Query("statusId")); v != "" {
if id, err := strconv.ParseUint(v, 10, 64); err == nil {
q = q.Where("status_id = ?", id)
}
}
if v := strings.TrimSpace(c.Query("shipped")); v != "" {
if v == "true" {
q = q.Where("ship_date IS NOT NULL")
}
if v == "false" {
q = q.Where("ship_date IS NULL")
}
}
var total int64
_ = q.Count(&total).Error
var list []domain.Order
_ = q.Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&list).Error
c.JSON(http.StatusOK, domain.OK(gin.H{
"list": list,
"total": total,
}))
}
func (h *Handler) OrderGet(c *gin.Context) {
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
var row domain.Order
if err := h.db.Where("id = ?", id).First(&row).Error; err != nil {
c.JSON(http.StatusNotFound, domain.Fail("不存在"))
return
}
c.JSON(http.StatusOK, domain.OK(row))
}
func (h *Handler) OrderCreate(c *gin.Context) {
uidAny, _ := c.Get(middleware.CtxUserIDKey)
uid, _ := uidAny.(uint64)
var req orderReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("参数错误"))
return
}
orderDate, err := time.Parse("2006-01-02", strings.TrimSpace(req.OrderDate))
if err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("下单日期格式错误"))
return
}
var shipDate *time.Time
if strings.TrimSpace(req.ShipDate) != "" {
t, err := time.Parse("2006-01-02", strings.TrimSpace(req.ShipDate))
if err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("出货日期格式错误"))
return
}
shipDate = &t
}
a, err := decimal.NewFromString(strings.ReplaceAll(strings.TrimSpace(req.AmountA), ",", ""))
if err != nil || a.IsNegative() {
c.JSON(http.StatusBadRequest, domain.Fail("下单金额格式错误"))
return
}
b, err := decimal.NewFromString(strings.ReplaceAll(strings.TrimSpace(req.AmountB), ",", ""))
if err != nil || b.IsNegative() {
c.JSON(http.StatusBadRequest, domain.Fail("订单金额格式错误"))
return
}
row := domain.Order{
OrderNo: strings.TrimSpace(req.OrderNo),
OrderDate: orderDate,
ShipDate: shipDate,
AmountA: a.Round(2),
AmountB: b.Round(2),
CustomerID: req.CustomerID,
StatusID: req.StatusID,
Remark: req.Remark,
Source: "manual",
CreatedBy: uid,
}
if err := h.db.Create(&row).Error; err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("创建失败:"+err.Error()))
return
}
c.JSON(http.StatusOK, domain.OK(row))
}
func (h *Handler) OrderUpdate(c *gin.Context) {
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
var req orderReq
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("参数错误"))
return
}
var row domain.Order
if err := h.db.Where("id = ?", id).First(&row).Error; err != nil {
c.JSON(http.StatusNotFound, domain.Fail("不存在"))
return
}
orderDate, err := time.Parse("2006-01-02", strings.TrimSpace(req.OrderDate))
if err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("下单日期格式错误"))
return
}
var shipDate *time.Time
if strings.TrimSpace(req.ShipDate) != "" {
t, err := time.Parse("2006-01-02", strings.TrimSpace(req.ShipDate))
if err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("出货日期格式错误"))
return
}
shipDate = &t
}
a, err := decimal.NewFromString(strings.ReplaceAll(strings.TrimSpace(req.AmountA), ",", ""))
if err != nil || a.IsNegative() {
c.JSON(http.StatusBadRequest, domain.Fail("下单金额格式错误"))
return
}
b, err := decimal.NewFromString(strings.ReplaceAll(strings.TrimSpace(req.AmountB), ",", ""))
if err != nil || b.IsNegative() {
c.JSON(http.StatusBadRequest, domain.Fail("订单金额格式错误"))
return
}
row.OrderNo = strings.TrimSpace(req.OrderNo)
row.OrderDate = orderDate
row.ShipDate = shipDate
row.AmountA = a.Round(2)
row.AmountB = b.Round(2)
row.CustomerID = req.CustomerID
row.StatusID = req.StatusID
row.Remark = req.Remark
if err := h.db.Save(&row).Error; err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("更新失败:"+err.Error()))
return
}
c.JSON(http.StatusOK, domain.OK(row))
}
func (h *Handler) OrderDelete(c *gin.Context) {
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
if err := h.db.Delete(&domain.Order{}, id).Error; err != nil {
c.JSON(http.StatusBadRequest, domain.Fail("删除失败:"+err.Error()))
return
}
c.JSON(http.StatusOK, domain.OK(gin.H{}))
}