diff --git a/controllers/split_account_deduction_log.go b/controllers/split_account_deduction_log.go index 9830b7e..be166a6 100644 --- a/controllers/split_account_deduction_log.go +++ b/controllers/split_account_deduction_log.go @@ -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, + }) +} diff --git a/models/book_info.go b/models/book_info.go index 0c9b713..2eb552e 100644 --- a/models/book_info.go +++ b/models/book_info.go @@ -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:字数"` diff --git a/models/outbound_order.go b/models/outbound_order.go index d1a1fb7..8317570 100644 --- a/models/outbound_order.go +++ b/models/outbound_order.go @@ -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:出库总金额(分)"` diff --git a/models/receiving_order.go b/models/receiving_order.go index 238b999..a9660b4 100644 --- a/models/receiving_order.go +++ b/models/receiving_order.go @@ -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)"` diff --git a/models/request/split_account_deduction_log.go b/models/request/split_account_deduction_log.go index 22d80f1..8c7bc2b 100644 --- a/models/request/split_account_deduction_log.go +++ b/models/request/split_account_deduction_log.go @@ -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"` // 订单号 +} diff --git a/models/response/product.go b/models/response/product.go index 8016f42..eb4ae39 100644 --- a/models/response/product.go +++ b/models/response/product.go @@ -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 商品完整信息响应 diff --git a/models/response/split_account_deduction_log.go b/models/response/split_account_deduction_log.go index 4ac7d1f..36c3025 100644 --- a/models/response/split_account_deduction_log.go +++ b/models/response/split_account_deduction_log.go @@ -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{} diff --git a/models/response/statist.go b/models/response/statist.go index 1d71773..3f981b6 100644 --- a/models/response/statist.go +++ b/models/response/statist.go @@ -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"` // 库存量 diff --git a/models/shipping_order.go b/models/shipping_order.go index 720e1e7..a4557c5 100644 --- a/models/shipping_order.go +++ b/models/shipping_order.go @@ -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:预计到达时间(时间戳秒)"` diff --git a/routes/routes.go b/routes/routes.go index 2aea2cd..2d43748 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -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") diff --git a/service/book.go b/service/book.go index 16ea0be..a542670 100644 --- a/service/book.go +++ b/service/book.go @@ -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, diff --git a/service/product.go b/service/product.go index 1bf6432..c60c640 100644 --- a/service/product.go +++ b/service/product.go @@ -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 } diff --git a/service/split_account_deduction_log.go b/service/split_account_deduction_log.go index 7c4a2b0..19d4f32 100644 --- a/service/split_account_deduction_log.go +++ b/service/split_account_deduction_log.go @@ -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 +} diff --git a/service/statist.go b/service/statist.go index f28638f..3d172b4 100644 --- a/service/statist.go +++ b/service/statist.go @@ -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{