daShangDao_psiServer/service/sales.go
Administrator a2ea0c3a40 1.在这个接口里 /api/product/updateNameAndImages,添加多张图片时,并未覆盖原来的多张图片。(Y)
2.从系统导出的excel数据,在外部对excel某一列进行更改时,新增的要回传到原来的地方;并对改动的地方进行覆盖。
3.销售单管理、出库管理、发货单三个接口里面展示第三方订单编号和快递单号
4.选择多个仓库时,只要选择发货单子就会报错
5.在这个/api/split-account-deduction-log/create接口里,当传参时,如果参数 total_amount 是0,则会报错 {"code":204,"data":{},"msg":"TotalAmount不能为空"} 0是金额数字,不能当空值进行判断(T)
传递参数created_by,没有往数据表里写入
6.商品销毁的同时写入日志,也能通过读取这个日志,还原销毁的商品。传出这个新增的接口
7.新增一个不需要签名认证的分帐扣钱日志列表接口,新增一个返回字段buniness_no,并对这个字段进行模糊查询。
测试接口:/open/split-account-deduction-log/list
8.增加个新接口:首先 调用 /api/sales-order/create 创建销售订单的时候会锁定库存,
现在我需要一个解锁库存的接口,传递参数是订单编号
POST /api/sales-order/unlock-inventory // 解锁销售订单库存
/api/split-account-deduction-log/update /api/sales-order/unlock-inventory 在这两个接口里不需要签名认证
/api/sales-order/unlock-inventory 在这个接口里面返回解锁的所有商品信息
/api/split-account-deduction-log/update  在这个接口里面的status也需要更改,status没有变化
2026-06-24 09:41:12 +08:00

338 lines
12 KiB
Go

package service
import (
"encoding/json"
"psi/database"
"psi/models"
systemReq "psi/models/request"
systemRes "psi/models/response"
"psi/utils"
"gorm.io/gorm"
)
type SalesService struct{}
// GetSalesOrderList 获取销售订单列表
func (s *SalesService) GetSalesOrderList(req systemReq.GetSalesOrderListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderListResponse, error) {
databaseConn := database.OptionalDB(db...)
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 || req.PageSize > 100 {
req.PageSize = 20
}
query := databaseConn.Model(&models.SalesOrder{}).Where("sales_order.is_del = ?", 0)
if role == 128 {
query = query.Where("sales_order.sales_person_id = ?", creatorID)
}
if req.Status > 0 {
query = query.Where("sales_order.status = ?", req.Status)
}
if req.CustomerID > 0 {
query = query.Where("sales_order.customer_id = ?", req.CustomerID)
}
if req.WarehouseID > 0 {
query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
}
if req.SoNo != "" {
query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
}
if req.StartDate > 0 {
query = query.Where("sales_order.created_at >= ?", req.StartDate)
}
if req.EndDate > 0 {
query = query.Where("sales_order.created_at <= ?", req.EndDate)
}
if req.AssociationOrderNo != "" {
query = query.Where("sales_order.association_order_no LIKE ?", "%"+req.AssociationOrderNo+"%")
}
if req.LogisticsNo != "" {
subQuery := databaseConn.Model(&models.SalesOrderItem{}).
Select("sales_order_id").
Where("logistics_no LIKE ? AND is_del = 0", "%"+req.LogisticsNo+"%")
query = query.Where("sales_order.id IN (?)", subQuery)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, utils.NewError("查询总数失败")
}
if total == 0 {
return &systemRes.SalesOrderListResponse{
List: []systemRes.SalesOrderItem{},
Total: 0,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
var orders []systemRes.SalesOrderWithInfo
offset := (req.Page - 1) * req.PageSize
if err := query.Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
Order("sales_order.created_at DESC").
Offset(offset).
Limit(req.PageSize).
Find(&orders).Error; err != nil {
return nil, utils.NewError("查询销售订单列表失败")
}
orderItems := make([]systemRes.SalesOrderItem, 0, len(orders))
for _, order := range orders {
var logisticsNos string
databaseConn.Table("sales_order_item").
Select("GROUP_CONCAT(DISTINCT logistics_no SEPARATOR ', ')").
Where("sales_order_id = ? AND is_del = ? AND logistics_no != ''", order.ID, 0).
Scan(&logisticsNos)
orderItems = append(orderItems, systemRes.ConvertSalesOrderToItem(
order.SalesOrder,
order.CustomerName,
order.WarehouseName,
logisticsNos,
))
}
return &systemRes.SalesOrderListResponse{
List: orderItems,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// GetSalesOrderDetailList 获取分页的销售订单详情列表(含明细)
func (s *SalesService) GetSalesOrderDetailList(req systemReq.GetSalesOrderDetailListRequest, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderDetailListResponse, error) {
databaseConn := database.OptionalDB(db...)
if req.Page < 1 {
req.Page = 1
}
if req.PageSize < 1 || req.PageSize > 100 {
req.PageSize = 20
}
query := databaseConn.Model(&models.SalesOrder{}).Where("sales_order.is_del = ?", 0)
if role == 128 {
query = query.Where("sales_order.sales_person_id = ?", creatorID)
}
//if req.Status > 0 {
// query = query.Where("sales_order.status = ?", req.Status)
//}
//if req.CustomerID > 0 {
// query = query.Where("sales_order.customer_id = ?", req.CustomerID)
//}
//if req.WarehouseID > 0 {
// query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
//}
//if req.SoNo != "" {
// query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
//}
//if req.StartDate > 0 {
// query = query.Where("sales_order.created_at >= ?", req.StartDate)
//}
//if req.EndDate > 0 {
// query = query.Where("sales_order.created_at <= ?", req.EndDate)
//}
if req.Status > 0 {
query = query.Where("sales_order.status = ?", req.Status)
}
if req.CustomerID > 0 {
query = query.Where("sales_order.customer_id = ?", req.CustomerID)
}
if req.WarehouseID > 0 {
query = query.Where("sales_order.warehouse_id = ?", req.WarehouseID)
}
if req.SoNo != "" {
query = query.Where("sales_order.so_no LIKE ?", "%"+req.SoNo+"%")
}
if req.StartDate > 0 {
query = query.Where("sales_order.created_at >= ?", req.StartDate)
}
if req.EndDate > 0 {
query = query.Where("sales_order.created_at <= ?", req.EndDate)
}
if req.AssociationOrderNo != "" {
query = query.Where("sales_order.association_order_no LIKE ?", "%"+req.AssociationOrderNo+"%")
}
if req.LogisticsNo != "" {
subQuery := databaseConn.Model(&models.SalesOrderItem{}).
Select("sales_order_id").
Where("logistics_no LIKE ? AND is_del = 0", "%"+req.LogisticsNo+"%")
query = query.Where("sales_order.id IN (?)", subQuery)
}
var total int64
if err := query.Count(&total).Error; err != nil {
return nil, utils.NewError("查询总数失败")
}
if total == 0 {
return &systemRes.SalesOrderDetailListResponse{
List: []systemRes.SalesOrderDetailResponse{},
Total: 0,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// 查询分页的销售订单
var orders []systemRes.SalesOrderWithInfo
offset := (req.Page - 1) * req.PageSize
if err := query.Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
Order("sales_order.created_at DESC").
Offset(offset).
Limit(req.PageSize).
Find(&orders).Error; err != nil {
return nil, utils.NewError("查询销售订单列表失败")
}
// 提取订单ID列表
orderIDs := make([]int64, len(orders))
for i, order := range orders {
orderIDs[i] = order.ID
}
// 批量查询所有订单的明细项(含商品信息)
var allItems []systemRes.SalesOrderItemWithProduct
if err := databaseConn.Model(&models.SalesOrderItem{}).
Select("sales_order_item.*, p.name as product_name, p.barcode as product_code, p.category_id, p.sale_price as product_sale_price, c.name as category_name, p.live_image ,lt.code as location_code").
Joins("LEFT JOIN product p ON sales_order_item.product_id = p.id AND p.is_del = 0").
Joins("LEFT JOIN product_category c ON p.category_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN inventory_detail de on p.id = de.product_id AND de.is_del = 0").
Joins("LEFT JOIN location lt on de.location_id = lt.id").
Where("sales_order_item.sales_order_id IN ? AND sales_order_item.is_del = ?", orderIDs, 0).
Find(&allItems).Error; err != nil {
return nil, utils.NewError("查询订单明细失败")
}
// 按订单ID分组明细项
itemMap := make(map[int64][]systemRes.SalesOrderItemWithProduct)
for _, item := range allItems {
itemMap[item.SalesOrderID] = append(itemMap[item.SalesOrderID], item)
}
// 组装响应
detailList := make([]systemRes.SalesOrderDetailResponse, 0, len(orders))
for _, order := range orders {
items := itemMap[order.ID]
detailItems := make([]systemRes.SalesOrderDetailItem, 0, len(items))
for _, item := range items {
var imageList []string
if len(item.LiveImage) > 0 {
json.Unmarshal(item.LiveImage, &imageList)
}
detailItems = append(detailItems, systemRes.SalesOrderDetailItem{
ID: item.ID,
SalesOrderID: item.SalesOrderID,
ProductID: item.ProductID,
ProductName: item.ProductName,
ProductCode: item.ProductCode,
ProductSalePrice: item.ProductSalePrice,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
LiveImage: imageList,
Quantity: item.Quantity,
AllocatedQuantity: item.AllocatedQuantity,
ShippedQuantity: item.ShippedQuantity,
UnitPrice: item.UnitPrice,
Amount: item.Amount,
ReceiverName: item.ReceiverName,
ReceiverPhone: item.ReceiverPhone,
ReceiverAddress: item.ReceiverAddress,
LogisticsCompany: item.LogisticsCompany,
LogisticsNo: item.LogisticsNo,
LocationCode: item.LocationCode,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
detailList = append(detailList, detail)
}
return &systemRes.SalesOrderDetailListResponse{
List: detailList,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// GetSalesOrderDetail 获取销售订单详情
func (s *SalesService) GetSalesOrderDetail(id int64, creatorID int64, role int64, db ...*gorm.DB) (*systemRes.SalesOrderDetailResponse, error) {
databaseConn := database.OptionalDB(db...)
query := databaseConn.Model(&models.SalesOrder{}).
Select("sales_order.*, c.name as customer_name, w.name as warehouse_name").
Joins("LEFT JOIN customer c ON sales_order.customer_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN warehouse w ON sales_order.warehouse_id = w.id AND w.is_del = 0").
Where("sales_order.id = ? AND sales_order.is_del = ?", id, 0)
if role == 128 {
query = query.Where("sales_order.sales_person_id = ?", creatorID)
}
var order systemRes.SalesOrderWithInfo
result := query.First(&order)
if result.Error != nil {
return nil, utils.NewError("销售订单不存在")
}
var items []systemRes.SalesOrderItemWithProduct
databaseConn.Model(&models.SalesOrderItem{}).
Select("sales_order_item.*, p.name as product_name, p.barcode as product_code, p.category_id,p.sale_price as product_sale_price, c.name as category_name, p.live_image, lt.code as location_code").
Joins("LEFT JOIN product p ON sales_order_item.product_id = p.id AND p.is_del = 0").
Joins("LEFT JOIN product_category c ON p.category_id = c.id AND c.is_del = 0").
Joins("LEFT JOIN inventory_detail de on p.id = de.product_id AND de.is_del = 0").
Joins("LEFT JOIN location lt on de.location_id = lt.id").
Where("sales_order_item.sales_order_id = ? AND sales_order_item.is_del = ?", order.ID, 0).
Find(&items)
detailItems := make([]systemRes.SalesOrderDetailItem, 0, len(items))
for _, item := range items {
var imageList []string
if len(item.LiveImage) > 0 {
json.Unmarshal(item.LiveImage, &imageList)
}
detailItems = append(detailItems, systemRes.SalesOrderDetailItem{
ID: item.ID,
SalesOrderID: item.SalesOrderID,
ProductID: item.ProductID,
ProductName: item.ProductName,
ProductCode: item.ProductCode,
ProductSalePrice: item.ProductSalePrice,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
LiveImage: imageList,
Quantity: item.Quantity,
AllocatedQuantity: item.AllocatedQuantity,
ShippedQuantity: item.ShippedQuantity,
UnitPrice: item.UnitPrice,
Amount: item.Amount,
ReceiverName: item.ReceiverName,
ReceiverPhone: item.ReceiverPhone,
ReceiverAddress: item.ReceiverAddress,
LogisticsCompany: item.LogisticsCompany,
LogisticsNo: item.LogisticsNo,
LocationCode: item.LocationCode,
CreatedAt: item.CreatedAt,
UpdatedAt: item.UpdatedAt,
})
}
detail := systemRes.ConvertSalesOrderToDetail(order.SalesOrder, order.CustomerName, order.WarehouseName, detailItems)
return &detail, nil
}