1、优化零售明细excel导出,解决导出全量数量超时报错的问题;
This commit is contained in:
parent
4e47b69ef1
commit
6d801b1404
|
@ -276,3 +276,53 @@ func GetCategoryLevels(categoryID uint32) (CategoryLevels, error) {
|
|||
|
||||
return levels, nil
|
||||
}
|
||||
|
||||
// GetAllCategories 查询所有分类并返回一个映射
|
||||
func GetAllCategories() (map[uint32]Category, error) {
|
||||
var categories []Category
|
||||
err := orm.Eloquent.Model(&Category{}).Find(&categories).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
categoryMap := make(map[uint32]Category)
|
||||
for _, category := range categories {
|
||||
categoryMap[category.ID] = category
|
||||
}
|
||||
return categoryMap, nil
|
||||
}
|
||||
|
||||
// GetCategoryLevelsFromMap 从预加载的分类信息中获取层级
|
||||
func GetCategoryLevelsFromMap(categoryID uint32, categoryMap map[uint32]Category) CategoryLevels {
|
||||
var levels CategoryLevels
|
||||
|
||||
// 维持当前分类的ID
|
||||
currentID := categoryID
|
||||
levelCount := 0
|
||||
|
||||
for currentID != 0 && levelCount < 3 {
|
||||
currentCategory, exists := categoryMap[currentID]
|
||||
if !exists {
|
||||
break
|
||||
}
|
||||
|
||||
// 根据分类编号的长度判断层级
|
||||
numberLength := len(currentCategory.Number)
|
||||
switch numberLength {
|
||||
case 3:
|
||||
levels.Level1 = currentCategory // 一级分类
|
||||
case 6:
|
||||
levels.Level2 = currentCategory // 二级分类
|
||||
case 9:
|
||||
levels.Level3 = currentCategory // 三级分类
|
||||
default:
|
||||
return levels // 超过9位返回空
|
||||
}
|
||||
|
||||
// 移动到上级分类
|
||||
currentID = currentCategory.Pid
|
||||
levelCount++
|
||||
}
|
||||
|
||||
return levels
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -1345,6 +1346,40 @@ func NewErpBillSn() string {
|
|||
}
|
||||
}
|
||||
|
||||
// 添加零售订单的银行流水号
|
||||
func erpOrderSetBankTrxNoAI(list []ErpOrder) {
|
||||
if len(list) == 0 {
|
||||
return // 如果列表为空,直接返回
|
||||
}
|
||||
|
||||
// 提取所有的 BillSn
|
||||
billSnList := make([]string, len(list))
|
||||
for i, order := range list {
|
||||
billSnList[i] = order.BillSn
|
||||
}
|
||||
|
||||
// 批量查询
|
||||
var orderPayWays []ErpOrderRecord
|
||||
err := orm.Eloquent.Table("erp_order_record").
|
||||
Where("bill_sn IN (?) AND status = ?", billSnList, PayOk).
|
||||
Find(&orderPayWays).Error
|
||||
if err != nil {
|
||||
logger.Error("SetBankTrxNo query erp_order_record err:", logger.Field("err", err))
|
||||
return
|
||||
}
|
||||
|
||||
// 将银行流水号映射到订单
|
||||
bankTrxNoMap := make(map[string]string)
|
||||
for _, record := range orderPayWays {
|
||||
bankTrxNoMap[record.BillSn] = record.BankTrxNo
|
||||
}
|
||||
|
||||
// 设置每个订单的银行流水号
|
||||
for i := range list {
|
||||
list[i].BankTrxNo = bankTrxNoMap[list[i].BillSn]
|
||||
}
|
||||
}
|
||||
|
||||
// 添加零售订单的银行流水号
|
||||
func erpOrderSetBankTrxNo(list []ErpOrder) {
|
||||
for i, _ := range list {
|
||||
|
@ -1467,6 +1502,171 @@ func (m *ErpOrder) SetRetailDetailCommodity() {
|
|||
m.Commodities = respOrderCommodities
|
||||
}
|
||||
|
||||
// ErpOrderRetailDetailSetCommodityAI 添加零售明细中订单的商品信息
|
||||
func ErpOrderRetailDetailSetCommodityAI(list []ErpOrder) {
|
||||
// 构建订单ID的切片
|
||||
var orderIDs []uint32
|
||||
for _, order := range list {
|
||||
orderIDs = append(orderIDs, order.ID)
|
||||
}
|
||||
|
||||
// 批量查询所有商品信息
|
||||
var orderCommodities []ErpOrderCommodity
|
||||
err := orm.Eloquent.Table("erp_order_commodity").Find(&orderCommodities).Error
|
||||
if err != nil {
|
||||
logger.Error("Batch query erp_order_commodity err:", logger.Field("err", err))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个映射,便于根据订单ID查找商品信息
|
||||
commodityMap := make(map[uint32][]ErpOrderCommodity)
|
||||
for _, commodity := range orderCommodities {
|
||||
commodityMap[commodity.ErpOrderId] = append(commodityMap[commodity.ErpOrderId], commodity)
|
||||
}
|
||||
|
||||
// 批量查询所有已售的非串码商品信息
|
||||
var stockCommodities []ErpStockCommodity
|
||||
err = orm.Eloquent.Table("erp_stock_commodity").Where("state = ? and imei = ?", SoldOut, "").Find(&stockCommodities).Error
|
||||
if err != nil {
|
||||
logger.Error("Batch query erp_stock_commodity err:", logger.Field("err", err))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建一个映射,便于根据库存商品ID查找商品信息
|
||||
stockMap := make(map[uint32]ErpStockCommodity)
|
||||
for _, stock := range stockCommodities {
|
||||
stockMap[stock.ID] = stock
|
||||
}
|
||||
|
||||
// 批量查询销售员信息
|
||||
var salesmanInfo []ErpOrderSales
|
||||
err = orm.Eloquent.Model(&ErpOrderSales{}).Find(&salesmanInfo).Error
|
||||
if err != nil {
|
||||
logger.Error("Batch query ErpOrderSales err:", logger.Field("err", err))
|
||||
return
|
||||
}
|
||||
|
||||
// 创建用户信息的映射,便于快速查找
|
||||
salesMap := make(map[uint32][]ErpOrderSales)
|
||||
for _, user := range salesmanInfo {
|
||||
salesMap[user.ErpOrderId] = append(salesMap[user.ErpOrderId], user)
|
||||
}
|
||||
|
||||
// 批量查询系统用户信息
|
||||
userMap, err := GetSysUserInfoByIds()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 批量查询商品信息
|
||||
var erpCommodities []ErpCommodity
|
||||
err = orm.Eloquent.Table("erp_commodity").Find(&erpCommodities).Error
|
||||
if err != nil {
|
||||
logger.Error("Batch query erp_commodity err:", logger.Field("err", err))
|
||||
return
|
||||
}
|
||||
erpCommodityMap := make(map[uint32]ErpCommodity)
|
||||
for _, commodity := range erpCommodities {
|
||||
erpCommodityMap[commodity.ID] = commodity
|
||||
}
|
||||
|
||||
for i := range list {
|
||||
list[i].SetRetailDetailCommodityAI(commodityMap[list[i].ID], stockMap)
|
||||
list[i].StorePer = tools.RoundToTwoDecimalPlaces(list[i].StorePer)
|
||||
|
||||
if list[i].RetailType == RetailTypeRejected { // 退货订单,金额需要转换为负值
|
||||
list[i].TotalRetailPrice = -math.Abs(list[i].TotalRetailPrice)
|
||||
list[i].TotalAmount = -math.Abs(list[i].TotalAmount)
|
||||
list[i].TotalCount = -int32(math.Abs(float64(list[i].TotalCount)))
|
||||
list[i].TotalSalesProfit = -list[i].TotalSalesProfit
|
||||
list[i].TotalStaffProfit = -list[i].TotalStaffProfit
|
||||
list[i].TotalDiscount = -math.Abs(list[i].TotalDiscount)
|
||||
list[i].VmCount = -uint32(math.Abs(float64(list[i].VmCount)))
|
||||
if list[i].TotalStaffProfit > 0 {
|
||||
list[i].StorePer = math.Abs(list[i].StorePer)
|
||||
} else {
|
||||
list[i].StorePer = -math.Abs(list[i].StorePer)
|
||||
}
|
||||
}
|
||||
|
||||
_ = list[i].SetOrderSalesmanAI(erpCommodityMap, salesMap, userMap)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *ErpOrder) SetRetailDetailCommodityAI(orderCommodities []ErpOrderCommodity, stockMap map[uint32]ErpStockCommodity) {
|
||||
var respOrderCommodities []ErpOrderCommodity
|
||||
for _, item := range orderCommodities {
|
||||
fmt.Println("orderId is:", item.ErpOrderId)
|
||||
if m.RetailType == RetailTypeRejected { // 退货订单,金额需要转换为负值
|
||||
item.Count = -item.Count
|
||||
item.RetailPrice = -item.RetailPrice
|
||||
item.SalePrice = -item.SalePrice
|
||||
item.Amount = -item.Amount
|
||||
item.SaleDiscount = -item.SaleDiscount
|
||||
item.MemberDiscount = -item.MemberDiscount
|
||||
item.VmDiscount = -item.VmDiscount
|
||||
item.ReceivedAmount = -item.ReceivedAmount
|
||||
item.RejectedAmount = -item.RejectedAmount
|
||||
item.SalesProfit = -item.SalesProfit
|
||||
item.StaffProfit = -item.StaffProfit
|
||||
item.StaffCostPrice = -item.StaffCostPrice
|
||||
item.WholesalePrice = -item.WholesalePrice
|
||||
item.CouponDiscount = -item.CouponDiscount
|
||||
}
|
||||
item.StaffPrice = item.StaffCostPrice + item.WholesalePrice
|
||||
|
||||
if item.IMEIType == 2 || item.IMEIType == 3 || item.IMEI != "" { // 串码
|
||||
respOrderCommodities = append(respOrderCommodities, item)
|
||||
} else { // 非串码
|
||||
idList, err := stringToIntArray(item.ErpStockCommodityID)
|
||||
if err != nil {
|
||||
respOrderCommodities = append(respOrderCommodities, item)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, stockCommodityId := range idList {
|
||||
fmt.Println("stockCommodityId is:", stockCommodityId)
|
||||
var orderCommodity ErpOrderCommodity
|
||||
orderCommodity = item
|
||||
if m.RetailType == RetailTypeRejected { // 退货订单,数量需要转换为负值
|
||||
orderCommodity.Count = -1
|
||||
} else {
|
||||
orderCommodity.Count = 1
|
||||
}
|
||||
|
||||
nCount := math.Abs(float64(item.Count))
|
||||
orderCommodity.SaleDiscount = item.SaleDiscount / nCount
|
||||
orderCommodity.VmDiscount = item.VmDiscount / nCount
|
||||
orderCommodity.ReceivedAmount = item.ReceivedAmount / nCount
|
||||
orderCommodity.RejectedAmount = item.RejectedAmount / nCount
|
||||
orderCommodity.SalesProfit = item.SalesProfit / nCount
|
||||
orderCommodity.StaffProfit = item.StaffProfit / nCount
|
||||
|
||||
// 获取库存商品信息
|
||||
stockCommodity, exists := stockMap[stockCommodityId]
|
||||
if !exists {
|
||||
respOrderCommodities = append(respOrderCommodities, item)
|
||||
continue
|
||||
}
|
||||
|
||||
orderCommodity.ErpSupplierId = stockCommodity.ErpSupplierId
|
||||
orderCommodity.ErpSupplierName = stockCommodity.ErpSupplierName
|
||||
orderCommodity.WholesalePrice = stockCommodity.WholesalePrice
|
||||
orderCommodity.StaffCostPrice = stockCommodity.StaffCostPrice
|
||||
orderCommodity.StaffPrice = orderCommodity.WholesalePrice + orderCommodity.StaffCostPrice
|
||||
if m.RetailType == RetailTypeRejected { // 退货订单,数量需要转换为负值
|
||||
orderCommodity.WholesalePrice = -orderCommodity.WholesalePrice
|
||||
orderCommodity.StaffCostPrice = -orderCommodity.StaffCostPrice
|
||||
orderCommodity.StaffPrice = -orderCommodity.StaffPrice
|
||||
}
|
||||
respOrderCommodities = append(respOrderCommodities, orderCommodity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m.Commodities = respOrderCommodities
|
||||
}
|
||||
|
||||
// 添加订单的商品信息
|
||||
func erpOrderListSetCommodity(list []ErpOrder) {
|
||||
for i, _ := range list {
|
||||
|
@ -1631,6 +1831,69 @@ func (m *ErpOrder) SetOrderSalesmanRetailDetail(userId uint32) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetSysUserInfoByIds 批量获取用户信息
|
||||
func GetSysUserInfoByIds() (map[uint32]SysUser, error) {
|
||||
var userInfos []SysUser
|
||||
err := orm.Eloquent.Debug().Table("sys_user").Find(&userInfos).Error
|
||||
if err != nil {
|
||||
logger.Error("Batch query sys_user err:", logger.Field("err", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 创建用户信息的映射,便于快速查找
|
||||
userMap := make(map[uint32]SysUser)
|
||||
for _, user := range userInfos {
|
||||
if countDigits(user.Uid) == 8 {
|
||||
userMap[user.Uid] = user
|
||||
} else {
|
||||
userMap[uint32(user.UserId)] = user
|
||||
}
|
||||
}
|
||||
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
func (m *ErpOrder) SetOrderSalesmanAI(erpCommodityMap map[uint32]ErpCommodity, salesMap map[uint32][]ErpOrderSales, userMap map[uint32]SysUser) error {
|
||||
var salesProfit, staffProfit, totalStaffProfit float64
|
||||
//获取销售毛利、员工毛利数据
|
||||
for _, item := range m.Commodities {
|
||||
erpCommodity := erpCommodityMap[item.ErpCommodityId]
|
||||
salesProfit += item.SalesProfit * erpCommodity.Brokerage1 * 0.01
|
||||
staffProfit += item.StaffProfit * erpCommodity.Brokerage2 * 0.01
|
||||
totalStaffProfit += item.StaffProfit
|
||||
}
|
||||
// 四舍五入并保留两位小数
|
||||
salesProfit = math.Round(salesProfit*100) / 100
|
||||
staffProfit = math.Round(staffProfit*100) / 100
|
||||
totalStaffProfit = math.Round(totalStaffProfit*100) / 100
|
||||
|
||||
var salesmanInfo []ErpOrderSales
|
||||
salesmanInfo = salesMap[m.ID]
|
||||
|
||||
var salesmanList []ErpOrderSales
|
||||
for _, item := range salesmanInfo {
|
||||
item.SalesProfitPer = salesProfit / float64(len(salesmanInfo))
|
||||
item.StaffProfitPer = staffProfit / float64(len(salesmanInfo))
|
||||
|
||||
// 获取员工毛利
|
||||
userInfo := userMap[item.Uid]
|
||||
item.Name = userInfo.NickName
|
||||
item.SalesmanPer = totalStaffProfit * userInfo.SalesCommRate * 0.01 / float64(len(salesmanInfo))
|
||||
|
||||
salesmanList = append(salesmanList, item)
|
||||
}
|
||||
|
||||
if len(salesmanList) == 0 {
|
||||
m.Salesman = []ErpOrderSales{}
|
||||
} else {
|
||||
m.Salesman = salesmanList
|
||||
}
|
||||
|
||||
m.SalesmanList = ""
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 添加订单的销售员信息
|
||||
func erpOrderListSetSalesman(list []ErpOrder) {
|
||||
for i, _ := range list {
|
||||
|
@ -3600,6 +3863,12 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C
|
|||
}
|
||||
}
|
||||
|
||||
categoryMap, err := GetAllCategories()
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
logger.Error("GetAllCategories err:", logger.Field("err", err))
|
||||
}
|
||||
|
||||
var row []interface{}
|
||||
nAmount := 0.0
|
||||
nExcelStartRow := 0
|
||||
|
@ -3641,7 +3910,8 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C
|
|||
}
|
||||
|
||||
// 商品分类
|
||||
categoryLevels, _ := GetCategoryLevels(list[i].Commodities[rowId].ErpCategoryId)
|
||||
categoryID := list[i].Commodities[rowId].ErpCategoryId
|
||||
categoryLevels := GetCategoryLevelsFromMap(categoryID, categoryMap)
|
||||
|
||||
isIMEIType := "是"
|
||||
if list[i].Commodities[rowId].IMEIType == 1 {
|
||||
|
@ -3675,11 +3945,11 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C
|
|||
}
|
||||
}
|
||||
|
||||
salesMan1 := ""
|
||||
salesMan2 := ""
|
||||
// 单个订单的汇总数据只记录一次
|
||||
if !orderFlag {
|
||||
orderFlag = true
|
||||
salesMan1 := ""
|
||||
salesMan2 := ""
|
||||
nSalesProfitPer := 0.0
|
||||
nStaffProfitPer := 0.0
|
||||
nSalesmanPer := 0.0
|
||||
|
@ -3793,8 +4063,8 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C
|
|||
auditTime,
|
||||
list[i].StoreName,
|
||||
list[i].BankTrxNo,
|
||||
list[i].Salesman[0].Name, //销售员1
|
||||
list[i].Salesman[1].Name, //销售员2
|
||||
salesMan1, //销售员1
|
||||
salesMan2, //销售员2
|
||||
categoryLevels.Level1.Name, // 一级分类
|
||||
categoryLevels.Level2.Name, // 二级分类
|
||||
categoryLevels.Level3.Name, // 三级分类
|
||||
|
@ -3885,7 +4155,7 @@ func retailDetailExport(list []ErpOrder, sumData RetailDetailTotalData, c *gin.C
|
|||
auditTime,
|
||||
list[i].StoreName,
|
||||
list[i].BankTrxNo,
|
||||
list[i].Salesman[0].Name, //销售员1
|
||||
salesMan1, //销售员1
|
||||
"", //销售员2
|
||||
categoryLevels.Level1.Name, // 一级分类
|
||||
categoryLevels.Level2.Name, // 二级分类
|
||||
|
@ -4903,9 +5173,21 @@ func queryRetailDetailCommon(req *ErpOrderRetailDetailReq, c *gin.Context) (*Erp
|
|||
logger.Error("erp commodity list err:", logger.Field("err", err))
|
||||
return resp, err
|
||||
}
|
||||
ErpOrderRetailDetailSetCommodity(orders)
|
||||
erpOrderListSetSalesman(orders)
|
||||
erpOrderSetBankTrxNo(orders)
|
||||
// 进行批量处理
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
ErpOrderRetailDetailSetCommodityAI(orders) // 商品信息处理
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
erpOrderSetBankTrxNoAI(orders) // 银行交易号处理
|
||||
}()
|
||||
|
||||
wg.Wait() // 等待所有处理完成
|
||||
|
||||
fileUrl, err := retailDetailExport(orders, sumData, c)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue
Block a user