This commit is contained in:
Administrator 2026-06-27 10:51:03 +08:00
parent 9d9a94aac6
commit 2d00956212
14 changed files with 363 additions and 30 deletions

View File

@ -163,3 +163,55 @@ func (r *SplitAccountDeductionLogApi) DeleteSplitAccountDeductionLog(c *gin.Cont
systemRes.OkWithMessage("删除成功", c)
}
// GetSplitAccountDeductionLogSummary 获取分账扣钱日志汇总
func (r *SplitAccountDeductionLogApi) GetSplitAccountDeductionLogSummary(c *gin.Context) {
var req systemReq.GetSplitAccountDeductionLogSummaryRequest
if err := c.ShouldBindQuery(&req); err != nil {
ValidAndFail(constant.LoggerChannelRequest, "分账扣钱日志汇总请求参数异常", "参数错误: "+err.Error(), c, err)
return
}
createdBy := req.AboutId
if createdBy == "0" || createdBy == "1" {
createdBy = ""
}
result, err := splitAccountDeductionLogService.GetSplitAccountDeductionLogSummary(req, createdBy, database.GetDB(c))
if err != nil {
utils.FailWithRequestLog(constant.LoggerChannelWork, "分账扣钱日志汇总异常", err, c, req)
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": result,
})
}
// GetSplitAccountDeductionLogDetailList 获取分账扣钱日志详情列表
func (r *SplitAccountDeductionLogApi) GetSplitAccountDeductionLogDetailList(c *gin.Context) {
var req systemReq.GetSplitAccountDeductionLogDetailListRequest
if err := c.ShouldBindQuery(&req); err != nil {
ValidAndFail(constant.LoggerChannelRequest, "分账扣钱日志详情列表请求参数异常", "参数错误: "+err.Error(), c, err)
return
}
createdBy := req.AboutId
if createdBy == "0" || createdBy == "1" {
createdBy = ""
}
result, err := splitAccountDeductionLogService.GetSplitAccountDeductionLogDetailList(req, createdBy, database.GetDB(c))
if err != nil {
utils.FailWithRequestLog(constant.LoggerChannelWork, "分账扣钱日志详情列表异常", err, c, req)
return
}
c.JSON(http.StatusOK, gin.H{
"code": 200,
"data": result,
})
}

View File

@ -14,6 +14,7 @@ type BookInfo struct {
Author string `json:"author" gorm:"size:100;not null;default:'';comment:作者"`
Publishing string `json:"publishing" gorm:"size:50;not null;default:'';comment:出版社"`
PublicationTime int64 `json:"publication_time" gorm:"type:bigint;not null;default:0;comment:出版日期时间戳"`
PublicationDate string `json:"publication_date" gorm:"size:10;not null;default:'';comment:出版日期年-月"`
Binding string `json:"binding" gorm:"size:10;not null;default:'';comment:装帧"`
PagesCount int64 `json:"pages_count" gorm:"not null;default:0;comment:页数"`
WordsCount int64 `json:"words_count" gorm:"not null;default:0;comment:字数"`

View File

@ -6,6 +6,7 @@ type OutboundOrder struct {
OutNo string `json:"out_no" gorm:"size:100;not null;default:'';uniqueIndex;comment:出库单号"`
WaveTaskID int64 `json:"wave_task_id" gorm:"not null;default:0;index;comment:波次任务ID"`
WarehouseID int64 `json:"warehouse_id" gorm:"not null;default:0;comment:仓库ID"`
ShopId int64 `json:"shop_id" gorm:"type:bigint(20);default:0;comment:店铺ID"`
CustomerID int64 `json:"customer_id" gorm:"not null;default:0;comment:客户ID"`
TotalQuantity int64 `json:"total_quantity" gorm:"not null;default:0;comment:出库总数量"`
TotalAmount int64 `json:"total_amount" gorm:"not null;default:0;comment:出库总金额(分)"`

View File

@ -7,6 +7,7 @@ type ReceivingOrder struct {
PurchaseOrderID int64 `json:"purchase_order_id" gorm:"not null;default:0;index;comment:关联采购单ID可为空支持无来源入库"`
WaveTaskID int64 `json:"wave_task_id" gorm:"not null;default:0;index;comment:关联波次任务ID"`
WarehouseID int64 `json:"warehouse_id" gorm:"not null;default:0;index;comment:入库仓库ID"`
ShopId int64 `json:"shop_id" gorm:"type:bigint(20);default:0;comment:店铺ID"`
SupplierID int64 `json:"supplier_id" gorm:"not null;default:0;comment:供应商ID"`
ReceivingDate int64 `json:"receiving_date" gorm:"not null;default:0;comment:入库日期时间戳(秒)"`
Status int8 `json:"status" gorm:"not null;default:1;index;comment:状态(1:待收货/pending, 2:验收中/checking, 3:已完成/completed, 4:已取消/cancelled)"`

View File

@ -39,3 +39,16 @@ type UpdateSplitAccountDeductionLogRequest struct {
type DeleteSplitAccountDeductionLogRequest struct {
ID int64 `form:"id" binding:"required"`
}
// GetSplitAccountDeductionLogSummaryRequest 获取分账扣钱日志汇总请求
type GetSplitAccountDeductionLogSummaryRequest struct {
AboutId string `form:"about_id"` // 用户about_id作为created_by
PageNum int `form:"page_num"` // 页码
PageSize int `form:"page_size"` // 每页数量
}
// GetSplitAccountDeductionLogDetailListRequest 获取分账扣钱日志详情列表请求
type GetSplitAccountDeductionLogDetailListRequest struct {
AboutId string `form:"about_id"` // 用户about_id作为created_by
BusinessNo string `form:"business_no"` // 订单号
}

View File

@ -207,13 +207,16 @@ type ProductInShop struct {
// ProductInventoryWarehouse 商品库存仓库信息
type ProductInventoryWarehouse struct {
WarehouseID int64 `json:"warehouse_id"` // 仓库ID
WarehouseName string `json:"warehouse_name"` // 仓库名称
WarehouseCode string `json:"warehouse_code"` // 仓库编码
ProductName string `json:"product_name"` // 商品名称
ISBN string `json:"isbn"` // ISBN/条码
Appearance int64 `json:"appearance"` // 品相
TotalQuantity int64 `json:"total_quantity"` // 该仓库下该商品的总库存
WarehouseID int64 `json:"warehouse_id"` // 仓库ID
WarehouseName string `json:"warehouse_name"` // 仓库名称
WarehouseCode string `json:"warehouse_code"` // 仓库编码
LocationID int64 `json:"location_id"` // 库位ID
LocationName string `json:"location_name"` // 库位名称
Logistics *LogisticsResponse `json:"logistics,omitempty"` // 物流模板信息
ProductName string `json:"product_name"` // 商品名称
ISBN string `json:"isbn"` // ISBN/条码
Appearance int64 `json:"appearance"` // 品相
TotalQuantity int64 `json:"total_quantity"` // 该仓库下该商品的总库存
}
// ProductFullInfoResponse 商品完整信息响应

View File

@ -29,6 +29,24 @@ type SplitAccountDeductionLogItem struct {
UpdatedAt int64 `json:"updated_at"`
}
// SplitAccountDeductionLogSummaryItem 分账扣钱日志汇总项
type SplitAccountDeductionLogSummaryItem struct {
BusinessNo string `json:"business_no"`
ConfigName string `json:"config_name"`
DeductionDetails interface{} `json:"deduction_details"`
Total int64 `json:"total"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
// SplitAccountDeductionLogSummaryResponse 分账扣钱日志汇总响应
type SplitAccountDeductionLogSummaryResponse struct {
List []SplitAccountDeductionLogSummaryItem `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
}
// ConvertSplitAccountDeductionLogToItem 将模型转换为响应项
func ConvertSplitAccountDeductionLogToItem(log models.SplitAccountDeductionLog) SplitAccountDeductionLogItem {
var deductionDetails interface{}

View File

@ -4,7 +4,7 @@ package response
type DashboardStatistResponse struct {
TotalReceivingCount int64 `json:"total_receiving_count"` // 总入库次数
TotalOutboundCount int64 `json:"total_outbound_count"` // 总出库次数
TotalSaleCount int64 `json:"total_sale_count"` // 今日商品总
TotalSaleCount int64 `json:"total_sale_count"` // 今日销售
UserStats []UserStatItem `json:"user_stats"` // 个人统计数据
ProductTotal int64 `json:"product_total"` // 商品总量
InventoryTotal int64 `json:"inventory_total"` // 库存量

View File

@ -5,6 +5,7 @@ type ShippingOrder struct {
ID int64 `json:"id" gorm:"primarykey;comment:主键ID"`
ShippingNo string `json:"shipping_no" gorm:"size:64;not null;default:'';uniqueIndex;comment:发货单号"`
CustomerID int64 `json:"customer_id" gorm:"not null;default:0;index;comment:客户ID"`
ShopId int64 `json:"shop_id" gorm:"type:bigint(20);default:0;comment:店铺ID"`
Status int8 `json:"status" gorm:"not null;default:1;index;comment:状态1=待发货 2=已发货 3=已签收 4=已取消"`
ShippingTime *int64 `json:"shipping_time" gorm:"type:bigint;comment:发货时间(时间戳秒)"`
ExpectedArriveTime *int64 `json:"expected_arrive_time" gorm:"type:bigint;comment:预计到达时间(时间戳秒)"`

View File

@ -35,6 +35,7 @@ var locationImportApi = &controllers.LocationImportApi{}
var outTaskApi = &controllers.OutTaskApi{}
var logisticsApi = &controllers.LogisticsApi{}
var statistApi = &controllers.StatistApi{}
var storeInfoApi = &controllers.StoreInfoApi{}
var userTypeApi = &controllers.UserTypeApi{}
var splitAccountConfigApi = &controllers.SplitAccountConfigApi{}
var splitAccountDeductionLogApi = &controllers.SplitAccountDeductionLogApi{}
@ -112,6 +113,14 @@ func initRouter() (r *gin.Engine) {
sign.POST("/logistics/cancel", cancelLogisticsApi.CancelLogistics) // 取消物流单号
}
// 分账扣款日志签名查询接口仅签名认证无需JWT
splitAccountSign := api.Group("")
splitAccountSign.Use(middleware.APISign())
{
splitAccountSign.GET("/split-account-deduction-log/summary", splitAccountDeductionLogApi.GetSplitAccountDeductionLogSummary) // 获取分账扣钱日志汇总
splitAccountSign.GET("/split-account-deduction-log/detail-list", splitAccountDeductionLogApi.GetSplitAccountDeductionLogDetailList) // 获取分账扣钱日志详情列表
}
// 需要认证(JWT)但不签名验证的接口
authOnly := api.Group("")
authOnly.Use(middleware.JWTAuth())
@ -295,6 +304,7 @@ func initRouter() (r *gin.Engine) {
auth.GET("/dashboard/statist", statistApi.DashboardStatist) // 仪表盘统计
auth.GET("/dashboard/warehouse", statistApi.GetWarehouseStatist) // 获取仓库统计
auth.GET("/dashboard/order", statistApi.GetOrderStatist) // 获取订单统计
auth.GET("/dashboard/store-info", storeInfoApi.StoreInfo) // 店铺统计
// 管理员接口
admin := auth.Group("/admin")

View File

@ -14,6 +14,7 @@ import (
systemRes "psi/models/response"
"strconv"
"strings"
)
type BookService struct{}
@ -159,6 +160,16 @@ func (s *BookService) doBook(data systemReq.AddBookRequest) (int64, error) {
}
}
// publication_time 兼容秒级和毫秒级时间戳,格式化为 "年-月"
var publicationDate string
if data.PublicationTime > 0 {
ts := data.PublicationTime
if ts > 1e12 { // 毫秒级时间戳
ts /= 1000
}
publicationDate = time.Unix(ts, 0).Format("2006-01")
}
book := models.BookInfo{
Fid: data.Fid,
Type: data.Type,
@ -169,6 +180,7 @@ func (s *BookService) doBook(data systemReq.AddBookRequest) (int64, error) {
Author: data.Author,
Publishing: data.Publisher,
PublicationTime: data.PublicationTime,
PublicationDate: publicationDate,
Binding: data.BindingLayout,
PagesCount: data.PageCount,
WordsCount: data.WordCount,

View File

@ -1419,27 +1419,121 @@ func (s *ProductService) GetProductInventory(req systemReq.GetProductInventoryRe
}
var totalQuantity int64
var warehouses []systemRes.ProductInventoryWarehouse
// type=1: 按品相+ISBN+仓库分组后统计总数量
if req.Type == 1 {
type GroupStock struct {
TotalQuantity int64 `gorm:"column:total_quantity"`
WarehouseID int64 `gorm:"column:warehouse_id"`
WarehouseName string `gorm:"column:warehouse_name"`
WarehouseCode string `gorm:"column:warehouse_code"`
LocationID int64 `gorm:"column:location_id"`
LocationCode string `gorm:"column:location_code"`
TotalQuantity int64 `gorm:"column:total_quantity"`
LgID uint64 `gorm:"column:lg_id"`
LgTemplateName string `gorm:"column:lg_template_name"`
LgDeliveryProvince string `gorm:"column:lg_delivery_province"`
LgDeliveryCity string `gorm:"column:lg_delivery_city"`
LgDeliveryArea string `gorm:"column:lg_delivery_area"`
LgDeliveryAddress string `gorm:"column:lg_delivery_address"`
LgPricingMethod string `gorm:"column:lg_pricing_method"`
LgShipping string `gorm:"column:lg_shipping"`
LgFirWbv float64 `gorm:"column:lg_fir_wbv"`
LgFirPrice float64 `gorm:"column:lg_fir_price"`
LgContinueWbv float64 `gorm:"column:lg_continue_wbv"`
LgContinuePrice float64 `gorm:"column:lg_continue_price"`
LgContact string `gorm:"column:lg_contact"`
LgPhoneNumber uint64 `gorm:"column:lg_phone_number"`
LgFullAddress string `gorm:"column:lg_full_address"`
LgShippingRange string `gorm:"column:lg_shipping_range"`
LgWarehouseID uint64 `gorm:"column:lg_warehouse_id"`
LgRemark string `gorm:"column:lg_remark"`
LgStatus string `gorm:"column:lg_status"`
LgCreateTime *time.Time `gorm:"column:lg_create_time"`
LgUpdateTime *time.Time `gorm:"column:lg_update_time"`
}
var groupList []GroupStock
// 先根据商品的 ISBN 和品相,查询所有匹配的库存记录,再按仓库分组统计(可用量 = 总量 - 锁定量)
// 仓库和库位信息从 inventory_detail 表关联获取
databaseConn.Table("inventory").
Select(`
COALESCE(SUM(inventory.quantity - inventory.locked_quantity), 0) as total_quantity
inventory.warehouse_id,
COALESCE(w.name, '') as warehouse_name,
COALESCE(w.code, '') as warehouse_code,
COALESCE(MIN(l.id), 0) as location_id,
COALESCE(MIN(l.code), '') as location_code,
COALESCE(SUM(inventory.quantity - inventory.locked_quantity), 0) as total_quantity,
COALESCE(logistics.id, 0) as lg_id,
COALESCE(logistics.template_name, '') as lg_template_name,
COALESCE(logistics.delivery_province, '') as lg_delivery_province,
COALESCE(logistics.delivery_city, '') as lg_delivery_city,
COALESCE(logistics.delivery_area, '') as lg_delivery_area,
COALESCE(logistics.delivery_address, '') as lg_delivery_address,
COALESCE(logistics.pricing_method, '') as lg_pricing_method,
COALESCE(logistics.shipping, '') as lg_shipping,
COALESCE(logistics.fir_wbv, 0) as lg_fir_wbv,
COALESCE(logistics.fir_price, 0) as lg_fir_price,
COALESCE(logistics.continue_wbv, 0) as lg_continue_wbv,
COALESCE(logistics.continue_price, 0) as lg_continue_price,
COALESCE(logistics.contact, '') as lg_contact,
COALESCE(logistics.phone_number, 0) as lg_phone_number,
COALESCE(logistics.full_address, '') as lg_full_address,
COALESCE(logistics.shipping_range, '') as lg_shipping_range,
COALESCE(logistics.warehouse_id, 0) as lg_warehouse_id,
COALESCE(logistics.remark, '') as lg_remark,
COALESCE(logistics.status, '') as lg_status,
logistics.create_time as lg_create_time,
logistics.update_time as lg_update_time
`).
Joins("LEFT JOIN product p ON inventory.product_id = p.id AND p.is_del = ?", 0).
Joins("LEFT JOIN warehouse w ON inventory.warehouse_id = w.id AND w.is_del = 0").
Joins("LEFT JOIN logistics ON w.logistics_id = logistics.id AND logistics.del_flag = '0'").
Joins("LEFT JOIN inventory_detail d ON d.product_id = inventory.product_id AND d.warehouse_id = inventory.warehouse_id AND d.is_del = 0").
Joins("LEFT JOIN location l ON d.location_id = l.id AND l.is_del = 0").
Where("p.barcode = ? AND p.appearance = ? AND inventory.warehouse_id IS NOT NULL AND inventory.is_del = ?",
product.Barcode, product.Appearance, 0).
Group("inventory.warehouse_id").
Group("inventory.warehouse_id, w.name, w.code").
Scan(&groupList)
// 累加所有分组的可用数量
for _, group := range groupList {
totalQuantity += group.TotalQuantity
var lg *systemRes.LogisticsResponse
if group.LgID > 0 {
lg = &systemRes.LogisticsResponse{
Id: group.LgID,
TemplateName: group.LgTemplateName,
DeliveryProvince: group.LgDeliveryProvince,
DeliveryCity: group.LgDeliveryCity,
DeliveryArea: group.LgDeliveryArea,
DeliveryAddress: group.LgDeliveryAddress,
PricingMethod: group.LgPricingMethod,
Shipping: group.LgShipping,
FirWbv: group.LgFirWbv,
FirPrice: group.LgFirPrice,
ContinueWbv: group.LgContinueWbv,
ContinuePrice: group.LgContinuePrice,
Contact: group.LgContact,
PhoneNumber: group.LgPhoneNumber,
FullAddress: group.LgFullAddress,
ShippingRange: group.LgShippingRange,
WarehouseId: group.LgWarehouseID,
Remark: group.LgRemark,
Status: group.LgStatus,
CreateTime: group.LgCreateTime,
UpdateTime: group.LgUpdateTime,
}
}
warehouses = append(warehouses, systemRes.ProductInventoryWarehouse{
WarehouseID: group.WarehouseID,
WarehouseName: group.WarehouseName,
WarehouseCode: group.WarehouseCode,
LocationID: group.LocationID,
LocationName: group.LocationCode,
Logistics: lg,
TotalQuantity: group.TotalQuantity,
})
}
} else {
databaseConn.Table("inventory").
@ -1448,7 +1542,8 @@ func (s *ProductService) GetProductInventory(req systemReq.GetProductInventoryRe
Scan(&totalQuantity)
}
return &systemRes.ProductInventoryResponse{
Quantity: totalQuantity,
Quantity: totalQuantity,
Warehouses: warehouses,
}, nil
}

View File

@ -2,6 +2,7 @@ package service
import (
"encoding/json"
"fmt"
"psi/database"
"psi/models"
systemReq "psi/models/request"
@ -179,3 +180,124 @@ func (s *SplitAccountDeductionLogService) DeleteSplitAccountDeductionLog(req sys
return nil
}
// GetSplitAccountDeductionLogSummary 获取分账扣钱日志汇总
func (s *SplitAccountDeductionLogService) GetSplitAccountDeductionLogSummary(req systemReq.GetSplitAccountDeductionLogSummaryRequest, createdBy string, db ...*gorm.DB) (*systemRes.SplitAccountDeductionLogSummaryResponse, error) {
databaseConn := database.OptionalDB(db...)
if req.PageNum < 1 {
req.PageNum = 1
}
if req.PageSize < 1 || req.PageSize > 100 {
req.PageSize = 20
}
// 根据 createdBy 决定是否过滤
hasFilter := createdBy != ""
// 先查询分组总数
var total int64
var countArgs []interface{}
if hasFilter {
countSQL := "SELECT COUNT(*) FROM (SELECT business_no FROM split_account_deduction_log WHERE created_by = ? GROUP BY business_no) AS t"
countArgs = []interface{}{createdBy}
fmt.Printf("[SQL] summary-count: %s | args: %v\n", countSQL, countArgs)
if err := databaseConn.Raw(countSQL, countArgs...).Scan(&total).Error; err != nil {
return nil, utils.NewError("查询汇总总数失败")
}
} else {
countSQL := "SELECT COUNT(*) FROM (SELECT business_no FROM split_account_deduction_log GROUP BY business_no) AS t"
fmt.Printf("[SQL] summary-count: %s\n", countSQL)
if err := databaseConn.Raw(countSQL).Scan(&total).Error; err != nil {
return nil, utils.NewError("查询汇总总数失败")
}
}
// 查询分页数据
offset := (req.PageNum - 1) * req.PageSize
type rawResult struct {
BusinessNo string `gorm:"column:business_no"`
ConfigName string `gorm:"column:config_name"`
DeductionDetails datatypes.JSON `gorm:"column:deduction_details"`
Total int64 `gorm:"column:total"`
CreatedAt int64 `gorm:"column:created_at"`
UpdatedAt int64 `gorm:"column:updated_at"`
}
var results []rawResult
if hasFilter {
dataSQL := `SELECT MAX(business_no) AS business_no, MAX(config_name) AS config_name,
MAX(deduction_details) AS deduction_details, COUNT(*) AS total,
MIN(created_at) AS created_at, MIN(updated_at) AS updated_at
FROM split_account_deduction_log
WHERE created_by = ?
GROUP BY business_no
ORDER BY business_no DESC
LIMIT ? OFFSET ?`
fmt.Printf("[SQL] summary-data: WHERE created_by = '%s' GROUP BY business_no ORDER BY business_no DESC LIMIT %d OFFSET %d\n", createdBy, req.PageSize, offset)
if err := databaseConn.Raw(dataSQL, createdBy, req.PageSize, offset).Scan(&results).Error; err != nil {
return nil, utils.NewError("查询分账扣钱日志汇总失败")
}
} else {
dataSQL := `SELECT MAX(business_no) AS business_no, MAX(config_name) AS config_name,
MAX(deduction_details) AS deduction_details, COUNT(*) AS total,
MIN(created_at) AS created_at, MIN(updated_at) AS updated_at
FROM split_account_deduction_log
GROUP BY business_no
ORDER BY business_no DESC
LIMIT ? OFFSET ?`
fmt.Printf("[SQL] summary-data: GROUP BY business_no ORDER BY business_no DESC LIMIT %d OFFSET %d\n", req.PageSize, offset)
if err := databaseConn.Raw(dataSQL, req.PageSize, offset).Scan(&results).Error; err != nil {
return nil, utils.NewError("查询分账扣钱日志汇总失败")
}
}
var items []systemRes.SplitAccountDeductionLogSummaryItem
for _, r := range results {
var deductionDetails interface{}
if r.DeductionDetails != nil {
json.Unmarshal(r.DeductionDetails, &deductionDetails)
}
items = append(items, systemRes.SplitAccountDeductionLogSummaryItem{
BusinessNo: r.BusinessNo,
ConfigName: r.ConfigName,
DeductionDetails: deductionDetails,
Total: r.Total,
CreatedAt: r.CreatedAt,
UpdatedAt: r.UpdatedAt,
})
}
return &systemRes.SplitAccountDeductionLogSummaryResponse{
List: items,
Total: total,
Page: req.PageNum,
PageSize: req.PageSize,
}, nil
}
// GetSplitAccountDeductionLogDetailList 获取分账扣钱日志详情列表
func (s *SplitAccountDeductionLogService) GetSplitAccountDeductionLogDetailList(req systemReq.GetSplitAccountDeductionLogDetailListRequest, createdBy string, db ...*gorm.DB) ([]systemRes.SplitAccountDeductionLogItem, error) {
databaseConn := database.OptionalDB(db...)
query := databaseConn.Where("business_no = ?", req.BusinessNo)
if createdBy != "" {
query = query.Where("created_by = ?", createdBy)
fmt.Printf("[SQL] detail-list: SELECT * FROM split_account_deduction_log WHERE business_no = '%s' AND created_by = '%s' ORDER BY id ASC\n", req.BusinessNo, createdBy)
} else {
fmt.Printf("[SQL] detail-list: SELECT * FROM split_account_deduction_log WHERE business_no = '%s' ORDER BY id ASC\n", req.BusinessNo)
}
var logs []models.SplitAccountDeductionLog
if err := query.Order("id ASC").Find(&logs).Error; err != nil {
return nil, utils.NewError("查询分账扣钱日志详情列表失败")
}
var items []systemRes.SplitAccountDeductionLogItem
for _, log := range logs {
items = append(items, systemRes.ConvertSplitAccountDeductionLogToItem(log))
}
return items, nil
}

View File

@ -159,6 +159,8 @@ func (s *StatistService) DashboardStatist(req systemReq.DashboardStatistRequest,
startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix()
endOfDay := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location()).Unix()
hasExplicitDate := req.EndDate != 0
if req.StartDate == 0 {
req.StartDate = startOfDay
}
@ -166,7 +168,12 @@ func (s *StatistService) DashboardStatist(req systemReq.DashboardStatistRequest,
req.EndDate = endOfDay
}
statDateStr := now.Format("20060102")
var statDateStr string
if hasExplicitDate {
statDateStr = time.Unix(req.EndDate, 0).Format("20060102")
} else {
statDateStr = now.Format("20060102")
}
var statDate int64
if _, err := fmt.Sscanf(statDateStr, "%d", &statDate); err != nil {
return s.getDashboardStatRealtime(databaseConn, req.StartDate, req.EndDate)
@ -213,9 +220,13 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
Where("created_at >= ? AND created_at <= ? AND is_del = ?", startDate, endDate, 0)
saleOrderQuery.Count(&totalSaleCount)
endTime := time.Unix(endDate, 0)
singleDayStart := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, endTime.Location()).Unix()
singleDayEnd := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 23, 59, 59, 0, endTime.Location()).Unix()
var totalReceivingCount, totalOutboundCount int64
statistQuery := databaseConn.Model(&models.Statist{}).
Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", startDate, endDate, 0)
Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", singleDayStart, singleDayEnd, 0)
var statistList []models.Statist
if err := statistQuery.Find(&statistList).Error; err != nil {
@ -247,13 +258,13 @@ func (s *StatistService) getDashboardStatRealtime(databaseConn *gorm.DB, startDa
var userStatGroups []UserStatGroup
databaseConn.Model(&models.Statist{}).
Select("create_by, SUM(receiving_num) as total_receiving, SUM(outbound_num) as total_outbound").
Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", startDate, endDate, 0).
Where("stat_date >= ? AND stat_date <= ? AND is_del = ?", singleDayStart, singleDayEnd, 0).
Group("create_by").
Scan(&userStatGroups)
for _, group := range userStatGroups {
var employee models.Employee
if err := database.DB.Where("id = ?", group.CreateBy).First(&employee).Error; err == nil {
if err := databaseConn.Where("id = ?", group.CreateBy).First(&employee).Error; err == nil {
userStats = append(userStats, systemRes.UserStatItem{
UserID: employee.ID,
UserName: employee.Username,
@ -315,18 +326,11 @@ func (s *StatistService) GetWarehouseStatist(req systemReq.WarehouseStatistReque
req.EndDate = endOfDay
}
type WarehouseStat struct {
ProductTotal int64 `gorm:"column:product_total"`
InventoryTotal int64 `gorm:"column:inventory_total"`
}
var productTotal int64
databaseConn.Model(&models.Product{}).Where("is_del = ?", 0).Count(&productTotal)
var warehouseStat WarehouseStat
databaseConn.Table("(?) as p", databaseConn.Model(&models.Product{}).Where("is_del = ?", 0).Select("COUNT(*) as product_total")).
Select(`
p.product_total,
COALESCE((SELECT SUM(quantity) FROM inventory WHERE is_del = ?), 0) as inventory_total
`, 0).
Scan(&warehouseStat)
var inventoryTotal int64
databaseConn.Model(&models.Inventory{}).Where("is_del = ?", 0).Select("COALESCE(SUM(quantity), 0)").Row().Scan(&inventoryTotal)
type DailyStat struct {
TodayInbound int64 `gorm:"column:today_inbound"`
@ -347,8 +351,8 @@ func (s *StatistService) GetWarehouseStatist(req systemReq.WarehouseStatistReque
Scan(&dailyStat)
return &systemRes.WarehouseStatistResponse{
ProductTotal: warehouseStat.ProductTotal,
InventoryTotal: warehouseStat.InventoryTotal,
ProductTotal: productTotal,
InventoryTotal: inventoryTotal,
TodayInbound: dailyStat.TodayInbound,
TodayOutbound: dailyStat.TodayOutbound,
YesterdayInbound: dailyStat.YesterdayInbound,
@ -408,7 +412,7 @@ func (s *StatistService) GetOrderStatist(req systemReq.OrderStatistRequest, db .
COALESCE(SUM(CASE WHEN created_at >= ? AND created_at <= ? AND status IN (?, ?) THEN 1 ELSE 0 END), 0) as yesterday_pending
`, req.StartDate, req.EndDate, req.StartDate, req.EndDate, req.StartDate, req.EndDate, StatusShipped, req.StartDate, req.EndDate, StatusShipped, StatusCancelled, req.StartDate, req.EndDate, StatusDraft, StatusConfirmed,
yesterdayStart, yesterdayEnd, yesterdayStart, yesterdayEnd, yesterdayStart, yesterdayEnd, StatusShipped, yesterdayStart, yesterdayEnd, StatusShipped, StatusCancelled, yesterdayStart, yesterdayEnd, StatusDraft, StatusConfirmed).
Where("is_del = ?", 0).
Where("is_del = ? AND created_at >= ? AND created_at <= ?", 0, yesterdayStart, req.EndDate).
Scan(&orderStat)
return &systemRes.OrderStatistResponse{