1、优化库存列表-产品库存汇总(按门店)查询慢的问题;

2、库存列表-产品库存汇总(按门店)导出excel优化,相同分类的商品排序在一起;
This commit is contained in:
chenlin 2024-10-25 16:09:30 +08:00
parent d0fd7663a2
commit 5c9cfd8e14

View File

@ -239,8 +239,8 @@ type ReportOtherDetailData struct {
EmployeePrice float64 `json:"employee_price"` // 入库员工成本价
}
// ReportByProductList 产品库存汇总(按门店)
func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*InventoryReportByProductResp, error) {
// ReportByProductList2 产品库存汇总(按门店)
func (m *InventoryReportByProductReq) ReportByProductList2(c *gin.Context) (*InventoryReportByProductResp, error) {
// 非管理员才判断所属门店
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
sysUser, err := GetSysUserByCtx(c)
@ -411,6 +411,192 @@ func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*Inve
return resp, nil
}
// ReportByProductList 产品库存汇总(按门店)
func (m *InventoryReportByProductReq) ReportByProductList(c *gin.Context) (*InventoryReportByProductResp, error) {
// 检查和设置门店权限...
if !(tools.GetRoleName(c) == "admin" || tools.GetRoleName(c) == "系统管理员") {
sysUser, err := GetSysUserByCtx(c)
if err != nil {
return nil, errors.New("操作失败:" + err.Error())
}
// 返回sysUser未过期的门店id列表
storeList := GetValidStoreIDs(sysUser.StoreData)
if len(storeList) > 0 {
m.StoreId = CompareLists(storeList, m.StoreId)
if len(m.StoreId) == 0 { // 没有匹配的数据,表示入参门店不是用户有权限的门店
return &InventoryReportByProductResp{}, nil
}
} else {
return nil, errors.New("用户未绑定门店")
}
}
resp := &InventoryReportByProductResp{
PageIndex: m.PageIndex,
PageSize: m.PageSize,
}
// 分页处理
page := m.PageIndex - 1
if page < 0 {
page = 0
}
if m.PageSize == 0 {
m.PageSize = 10
}
qs := orm.Eloquent.Debug().Table("erp_stock")
sumQs := orm.Eloquent.Debug().Table("erp_stock_commodity")
// 应用 StoreId 和其他条件
if len(m.StoreId) > 0 {
qs = qs.Where("store_id IN (?)", m.StoreId)
sumQs = sumQs.Where("store_id IN (?)", m.StoreId)
}
if len(m.CategoryID) > 0 {
qs = qs.Where("erp_category_id IN (?)", m.CategoryID)
sumQs = sumQs.Where("erp_category_id IN (?)", m.CategoryID)
}
if len(m.CommoditySerialNumber) > 0 { // 商品编号
qs = qs.Where("commodity_serial_number IN (?)", m.CommoditySerialNumber)
sumQs = sumQs.Where("commodity_serial_number IN (?)", m.CommoditySerialNumber)
}
if len(m.CommodityName) > 0 { // 商品名称
qs = qs.Where("erp_commodity_name IN (?)", m.CommodityName)
sumQs = sumQs.Where("erp_commodity_name IN (?)", m.CommodityName)
}
// 统计总条数并直接赋值给 resp.Total
var count int64
err := qs.Where("count != 0 or dispatch_count != 0 ").Count(&count).Error
if err != nil {
logger.Error("查询无库存列表数量失败", logger.Field("err", err))
return nil, err
}
resp.Total = uint32(count)
// 批量查询 EffectiveAmount 和 TransferAmount
effectiveAmounts, transferAmounts, err := getBatchAmounts(m.StoreId, m.CategoryID)
if err != nil {
return nil, err
}
// 获取库存商品数据并填充金额
var commodities []ErpStock
if m.IsExport == 1 { // 导出excel
err = qs.Order("erp_commodity_id, store_id desc").Find(&commodities).Error
} else {
err = qs.Order("erp_commodity_id, store_id desc").
Offset(page * m.PageSize).
Limit(m.PageSize).
Find(&commodities).Error
}
if err != nil && err != RecordNotFound {
logger.Error("查询无库存列表失败", logger.Field("err", err))
return nil, err
}
if m.IsExport == 1 {
SortStockCommodities(commodities)
}
// 构造报表数据
var reportList []ReportByProductData
for _, item := range commodities {
reportData := ReportByProductData{
StoreId: item.StoreId,
StoreName: item.StoreName,
CommoditySerialNumber: item.CommoditySerialNumber,
CommodityId: item.ErpCommodityId,
CommodityName: item.ErpCommodityName,
CategoryID: item.ErpCategoryId,
CategoryName: item.ErpCategoryName,
EffectiveCount: item.Count,
TransferCount: item.DispatchCount,
Count: item.Count + item.DispatchCount,
}
reportData.EffectiveAmount = effectiveAmounts[item.StoreId][item.ErpCommodityId]
reportData.TransferAmount = transferAmounts[item.StoreId][item.ErpCommodityId]
reportData.Amount = reportData.EffectiveAmount + reportData.TransferAmount
reportList = append(reportList, reportData)
}
// 获取汇总数据
sumData, err := getReportByProductSumData(sumQs)
if err != nil {
return nil, err
}
// 填充响应数据
resp.TotalEffectiveCount = sumData.TotalEffectiveCount
resp.TotalTransferCount = sumData.TotalTransferCount
resp.TotalCount = sumData.TotalCount
resp.TotalEffectiveAmount = math.Round(sumData.TotalEffectiveAmount*100) / 100
resp.TotalTransferAmount = math.Round(sumData.TotalTransferAmount*100) / 100
resp.TotalAmount = math.Round((resp.TotalEffectiveAmount+resp.TotalTransferAmount)*100) / 100
resp.List = reportList
if m.IsExport == 1 { // 导出excel
resp.ExportUrl, err = reportByProductExport(resp)
if err != nil {
return nil, err
}
resp.List = []ReportByProductData{}
}
return resp, nil
}
// 批量查询有效库存金额和调拨中金额
func getBatchAmounts(storeIDs, categoryIDs []uint32) (map[uint32]map[uint32]float64, map[uint32]map[uint32]float64, error) {
effectiveAmounts := make(map[uint32]map[uint32]float64)
transferAmounts := make(map[uint32]map[uint32]float64)
// 基于 storeIDs 和 categoryIDs 限制查询范围
query := orm.Eloquent.Debug().Table("erp_stock_commodity").
Select("store_id, erp_commodity_id, state, SUM(wholesale_price) AS amount").
Where("state IN (?, ?)", InStock, InAllot)
if len(storeIDs) > 0 {
query = query.Where("store_id IN (?)", storeIDs)
}
if len(categoryIDs) > 0 {
query = query.Where("erp_category_id IN (?)", categoryIDs)
}
rows, err := query.Group("store_id, erp_commodity_id, state").Rows()
if err != nil {
return nil, nil, err
}
defer rows.Close()
for rows.Next() {
var storeID, commodityID uint32
var state int
var amount float64
rows.Scan(&storeID, &commodityID, &state, &amount)
if state == InStock {
if _, exists := effectiveAmounts[storeID]; !exists {
effectiveAmounts[storeID] = make(map[uint32]float64)
}
effectiveAmounts[storeID][commodityID] = amount
} else if state == InAllot {
if _, exists := transferAmounts[storeID]; !exists {
transferAmounts[storeID] = make(map[uint32]float64)
}
transferAmounts[storeID][commodityID] = amount
}
}
return effectiveAmounts, transferAmounts, nil
}
// 查询有效库存金额
func getStockCommodityAmount(storeId, commodityId uint32) (float64, error) {
var nCount int64