diff --git a/controllers/barcode.go b/controllers/barcode.go index f70b35f..b70ac4e 100644 --- a/controllers/barcode.go +++ b/controllers/barcode.go @@ -11,10 +11,14 @@ import ( type BarcodeApi struct{} +// @title 条形码 var barcodeService = service.BarcodeService{} +// GenerateBarcode 生成条形码 func (r *BarcodeApi) GenerateBarcode(c *gin.Context) { + // 参数校验 var req systemReq.BarcodeRequest + // 参数绑定 if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "条形码生成请求参数异常", "参数错误: "+err.Error(), c, err) return diff --git a/controllers/book.go b/controllers/book.go index 8517028..3e94be9 100644 --- a/controllers/book.go +++ b/controllers/book.go @@ -16,6 +16,7 @@ var bookService = service.BookService{} // GetBookInfo 获取图书信息 func (r *BookApi) GetBookInfo(c *gin.Context) { + var req systemReq.BookRequest if err := c.ShouldBindQuery(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "获取图书信息请求参数异常", "参数错误: "+err.Error(), c, err) diff --git a/controllers/car.go b/controllers/car.go index 7b6ea61..afd56a7 100644 --- a/controllers/car.go +++ b/controllers/car.go @@ -18,6 +18,7 @@ type CarApi struct{} var carService = service.CarService{} +// GetCarList 获取小车列表 func (r *CarApi) GetCarList(c *gin.Context) { var req systemReq.QueryCarRequest if err := c.ShouldBindQuery(&req); err != nil { @@ -43,6 +44,7 @@ func (r *CarApi) GetCarList(c *gin.Context) { }) } +// GetCarDetail 获取小车详情 func (r *CarApi) GetCarDetail(c *gin.Context) { idStr := c.Param("id") diff --git a/controllers/employee.go b/controllers/employee.go index e4239c4..48d8e7c 100644 --- a/controllers/employee.go +++ b/controllers/employee.go @@ -313,10 +313,18 @@ func (r *EmployeeApi) GetUserList(c *gin.Context) { if err := c.ShouldBind(&req); err != nil { ValidAndFail(constant.LoggerChannelRequest, "获取用户列表请求参数异常", "参数错误: "+err.Error(), c, err) + // return } result, err := employeeService.GetUserList(req) + /*//输出用户列表 + if result == nil { + systemRes.FailWithMessage("无效的参数", c) + return + } + systemRes.OkWithDetailed(result, "查询成功", c)*/ + if err != nil { utils.FailWithRequestLog(constant.LoggerChannelWork, "获取用户列表异常", err, c, req) return diff --git a/controllers/goods_import.go b/controllers/goods_import.go index 7df763e..3d52989 100644 --- a/controllers/goods_import.go +++ b/controllers/goods_import.go @@ -21,6 +21,7 @@ type GoodsImportApi struct{} // ImportFromExcel 从Excel文件导入商品 // POST /api/goods/import-from-excel // multipart/form-data: file (Excel), user_id, warehouse_id + func (r *GoodsImportApi) ImportFromExcel(c *gin.Context) { // 获取 user_id userIDStr := c.PostForm("user_id") diff --git a/controllers/location.go b/controllers/location.go index 0bc2291..e0f8863 100644 --- a/controllers/location.go +++ b/controllers/location.go @@ -68,6 +68,7 @@ func (r *LocationApi) GetAllLocationList(c *gin.Context) { }) } +// GetLocationDetail 获取库位详情 func (r *LocationApi) GetLocationDetail(c *gin.Context) { idStr := c.Param("id") diff --git a/controllers/logistics.go b/controllers/logistics.go index 9c4cd72..8d78075 100644 --- a/controllers/logistics.go +++ b/controllers/logistics.go @@ -16,6 +16,7 @@ type LogisticsApi struct{} var logisticsService = service.LogisticsService{} +// GetLogisticsList 获取物流模板列表 func (r *LogisticsApi) GetLogisticsList(c *gin.Context) { var req request.QueryLogisticsRequest if err := c.ShouldBindQuery(&req); err != nil { @@ -41,6 +42,7 @@ func (r *LogisticsApi) GetLogisticsList(c *gin.Context) { }) } +// GetLogisticsDetail 获取物流模板详情 func (r *LogisticsApi) GetLogisticsDetail(c *gin.Context) { idStr := c.Param("id") @@ -64,6 +66,7 @@ func (r *LogisticsApi) GetLogisticsDetail(c *gin.Context) { response.OkWithDetailed(logistics, "查询成功", c) } +// CreateLogistics 创建物流模板 func (r *LogisticsApi) CreateLogistics(c *gin.Context) { var req request.CreateLogisticsRequest if err := c.ShouldBind(&req); err != nil { @@ -80,6 +83,7 @@ func (r *LogisticsApi) CreateLogistics(c *gin.Context) { response.OkWithDetailed(gin.H{"id": id}, "创建成功", c) } +// UpdateLogistics 更新物流模板 func (r *LogisticsApi) UpdateLogistics(c *gin.Context) { var req request.UpdateLogisticsRequest if err := c.ShouldBind(&req); err != nil { @@ -95,6 +99,7 @@ func (r *LogisticsApi) UpdateLogistics(c *gin.Context) { response.OkWithMessage("更新成功", c) } +// DeleteLogistics 删除物流模板 func (r *LogisticsApi) DeleteLogistics(c *gin.Context) { var req request.DeleteLogisticsRequest if err := c.ShouldBind(&req); err != nil { diff --git a/controllers/ocr.go b/controllers/ocr.go index eca0688..8738b7c 100644 --- a/controllers/ocr.go +++ b/controllers/ocr.go @@ -15,6 +15,7 @@ type OcrApi struct{} var ocrService = service.OcrService{} +// RecognizeText OCR识别 func (r *OcrApi) RecognizeText(c *gin.Context) { file, err := c.FormFile("image") if err != nil { diff --git a/controllers/product.go b/controllers/product.go index 5cdd81a..45f1c06 100644 --- a/controllers/product.go +++ b/controllers/product.go @@ -18,6 +18,7 @@ type ProductApi struct{} var productService = service.ProductService{} +// GetProductList 获取商品列表 func (r *ProductApi) GetProductList(c *gin.Context) { var req systemReq.GetProductListRequest @@ -47,6 +48,7 @@ func (r *ProductApi) GetProductList(c *gin.Context) { }) } +// GetDistributionProductList 获取分销商品列表 func (r *ProductApi) GetDistributionProductList(c *gin.Context) { var req systemReq.GetDistributionProductListRequest @@ -107,13 +109,50 @@ func (r *ProductApi) GetProductDetail(c *gin.Context) { }) } +// GetProductFullInfo 获取商品完整信息(无需签名认证) +func (r *ProductApi) GetProductFullInfo(c *gin.Context) { + var req systemReq.GetProductFullInfoRequest + + fmt.Printf("【断点1】接收到获取商品完整信息请求\n") + + if err := c.ShouldBindQuery(&req); err != nil { + fmt.Printf("【断点2】参数绑定失败: %v\n", err) + utils.InfoLog(constant.LoggerChannelRequest, map[string]interface{}{ + "action": "获取商品完整信息参数验证失败", + "error": err.Error(), + }) + systemRes.FailWithValidateMessage("参数错误: "+err.Error(), c) + return + } + + fmt.Printf("【断点3】参数验证通过 - ProductID: %d, UserID: %d\n", req.ProductID, req.UserID) + + result, err := productService.GetProductFullInfo(req, database.GetDB(c)) + if err != nil { + fmt.Printf("【断点4】查询商品完整信息失败: %v\n", err) + utils.FailWithRequestLog(constant.LoggerChannelWork, "获取商品完整信息异常", err, c, req) + return + } + + fmt.Printf("【断点5】查询成功,返回商品信息\n") + + c.JSON(http.StatusOK, gin.H{ + "code": 200, + "data": result, + }) +} + // SaveProduct 保存商品(添加或修改) func (r *ProductApi) SaveProduct(c *gin.Context) { var req systemReq.ProductRequest + + fmt.Printf("【断点1】接收到保存商品请求\n") if err := c.ShouldBind(&req); err != nil { + fmt.Printf("【断点2】参数绑定失败: %v\n", err) ValidAndFail(constant.LoggerChannelRequest, "保存商品请求参数异常", "参数错误: "+err.Error(), c, err) return } + fmt.Printf("【断点3】参数绑定成功, 商品信息: %+v\n", req) if len(req.LiveImage) == 0 { image, err := parseImageFromForm(c) if err != nil { @@ -276,6 +315,38 @@ func (r *ProductApi) BatchPushProducts(c *gin.Context) { systemRes.OkWithMessage("批量推送完成", c) } +/*func (r *ProductApi) BatchPushProducts(c *gin.Context) { +var req systemReq.BatchPushProductRequest + +if err := c.ShouldBind(&req); err != nil { + utils.InfoLog(constant.LoggerChannelRequest, map[string]interface{}{ + "action": "批量推送参数验证失败", + "error": err.Error(), + }) + ValidAndFail(constant.LoggerChannelRequest, "批量推送请求参数异常", "参数错误: "+err.Error(), c, err) + return +} + +utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "开始批量推送商品", + "shop_ids": req.ShopIDs, + "product_id": req.ProductID, +}) + +if err := productService.BatchPushProducts(req); err != nil { + utils.FailWithRequestLog(constant.LoggerChannelWork, "批量推送异常", err, c, req) + return +} + +utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "批量推送完成", + "product_id": req.ProductID, + "success": true, +}) + +systemRes.OkWithMessage("批量推送完成", c)*/ + +// GetProductLogList 商品日志列表 func (r *ProductApi) GetProductLogList(c *gin.Context) { var req systemReq.GetProductLogListRequest @@ -333,6 +404,7 @@ func (r *ProductApi) SaveProductLog(c *gin.Context) { systemRes.OkWithDetailed(gin.H{"id": id}, "操作成功", c) } +// AuditProductLog 审核商品日志 func (r *ProductApi) AuditProductLog(c *gin.Context) { var req systemReq.AuditProductLogRequest @@ -359,6 +431,7 @@ func (r *ProductApi) AuditProductLog(c *gin.Context) { systemRes.OkWithMessage("审核成功", c) } +// DeleteProductLog 删除商品日志 func (r *ProductApi) DeleteProductLog(c *gin.Context) { var req systemReq.DeleteProductLogRequest @@ -396,6 +469,7 @@ func (r *ProductApi) GetShopProductDetail(c *gin.Context) { }) } +// parseIds 解析ID列表 func parseIds(c *gin.Context) ([]int64, error) { var ids []int64 @@ -418,6 +492,7 @@ func parseIds(c *gin.Context) ([]int64, error) { return ids, nil } +// parseImageFromForm 解析图片列表 func parseImageFromForm(c *gin.Context) ([]string, error) { var images []string @@ -433,6 +508,7 @@ func parseImageFromForm(c *gin.Context) ([]string, error) { return images, nil } +// parseOldImageFromForm 解析图片列表 func parseOldImageFromForm(c *gin.Context) ([]string, error) { var images []string @@ -448,6 +524,7 @@ func parseOldImageFromForm(c *gin.Context) ([]string, error) { return images, nil } +// parseNewImageFromForm 解析图片列表 func parseNewImageFromForm(c *gin.Context) ([]string, error) { var images []string diff --git a/controllers/product_book.go b/controllers/product_book.go index a8848e8..ff8c6d7 100644 --- a/controllers/product_book.go +++ b/controllers/product_book.go @@ -39,8 +39,8 @@ func (r *ProductBookApi) List(c *gin.Context) { // Detail 获取商品反射详情 func (r *ProductBookApi) Detail(c *gin.Context) { - id := c.Query("id") - isbn := c.Query("isbn") + id := c.Query("id") // 商品ID + isbn := c.Query("isbn") // 商品ISBN if id == "" || isbn == "" { utils.ErrorLog(constant.LoggerChannelRequest, logrus.Fields(gin.H{ diff --git a/controllers/shop.go b/controllers/shop.go index 56e5eb7..64465d6 100644 --- a/controllers/shop.go +++ b/controllers/shop.go @@ -17,6 +17,7 @@ type ShopApi struct{} var shopService = service.ShopService{} +// GetShopList 获取店铺列表 func (r *ShopApi) GetShopList(c *gin.Context) { var req systemReq.QueryShopRequest if err := c.ShouldBindQuery(&req); err != nil { @@ -42,6 +43,7 @@ func (r *ShopApi) GetShopList(c *gin.Context) { }) } +// GetShopDetail 获取店铺详情 func (r *ShopApi) GetShopDetail(c *gin.Context) { idStr := c.Param("id") @@ -73,6 +75,7 @@ func (r *ShopApi) GetShopDetail(c *gin.Context) { systemRes.OkWithDetailed(shop, "查询成功", c) } +// CreateShop 创建店铺 func (r *ShopApi) CreateShop(c *gin.Context) { var req systemReq.CreateShopRequest if err := c.ShouldBind(&req); err != nil { @@ -89,6 +92,7 @@ func (r *ShopApi) CreateShop(c *gin.Context) { systemRes.OkWithDetailed(gin.H{"id": id}, "创建成功", c) } +// UpdateShop 更新店铺 func (r *ShopApi) UpdateShop(c *gin.Context) { var req systemReq.UpdateShopRequest if err := c.ShouldBind(&req); err != nil { @@ -104,6 +108,7 @@ func (r *ShopApi) UpdateShop(c *gin.Context) { systemRes.OkWithMessage("更新成功", c) } +// DeleteShop 删除店铺 func (r *ShopApi) DeleteShop(c *gin.Context) { var req systemReq.DeleteShopRequest if err := c.ShouldBind(&req); err != nil { diff --git a/controllers/warehouse.go b/controllers/warehouse.go index d1a504e..8563784 100644 --- a/controllers/warehouse.go +++ b/controllers/warehouse.go @@ -20,6 +20,7 @@ type WarehouseApi struct{} var warehouseService = service.WarehouseService{} +// GetWarehouseList 获取仓库列表 func (r *WarehouseApi) GetWarehouseList(c *gin.Context) { var req systemReq.QueryWarehouseRequest if err := c.ShouldBindQuery(&req); err != nil { @@ -54,6 +55,7 @@ func (r *WarehouseApi) GetWarehouseList(c *gin.Context) { }) } +// GetWarehouseDetail 获取仓库详情 func (r *WarehouseApi) GetWarehouseDetail(c *gin.Context) { idStr := c.Param("id") @@ -85,6 +87,7 @@ func (r *WarehouseApi) GetWarehouseDetail(c *gin.Context) { systemRes.OkWithDetailed(warehouse, "查询成功", c) } +// CreateWarehouse 创建仓库 func (r *WarehouseApi) CreateWarehouse(c *gin.Context) { var req systemReq.CreateWarehouseRequest if err := c.ShouldBind(&req); err != nil { @@ -134,6 +137,7 @@ func (r *WarehouseApi) DeleteWarehouse(c *gin.Context) { systemRes.OkWithMessage("删除成功", c) } +// LocationToCsv 导出库位 func (r *LocationApi) LocationToCsv(c *gin.Context) { var req systemReq.ExportLocationRequest if err := c.ShouldBindQuery(&req); err != nil { @@ -150,6 +154,7 @@ func (r *LocationApi) LocationToCsv(c *gin.Context) { systemRes.OkWithDetailed(result, "导出成功", c) } +// CsvToLocation 导入库位 func (r *LocationApi) CsvToLocation(c *gin.Context) { var req systemReq.ImportLocationRequest if err := c.ShouldBind(&req); err != nil { @@ -192,6 +197,7 @@ func (r *LocationApi) CsvToLocation(c *gin.Context) { systemRes.OkWithDetailed(result, result.Message, c) } +// GetUserWarehouseMappings 获取用户的仓库映射列表 func (r *WarehouseApi) GetUserWarehouseMappings(c *gin.Context) { data, err := warehouseService.GetUserWarehouseMappings() if err != nil { diff --git a/models/request/cancel_logistics.go b/models/request/cancel_logistics.go index 3e9e9fa..9c852c2 100644 --- a/models/request/cancel_logistics.go +++ b/models/request/cancel_logistics.go @@ -2,6 +2,6 @@ package request // CancelLogisticsRequest 取消物流单号请求 type CancelLogisticsRequest struct { - UserID int64 `form:"user_id" binding:"required"` - LogisticsNo string `form:"logistics_no" binding:"required"` + UserID int64 `form:"user_id" binding:"required"` // 用户ID + LogisticsNo string `form:"logistics_no" binding:"required"` // 物流单号 } diff --git a/models/request/goods_import.go b/models/request/goods_import.go index 7b5bb8f..7708a04 100644 --- a/models/request/goods_import.go +++ b/models/request/goods_import.go @@ -28,6 +28,7 @@ type GoodsImportResult struct { Message string } +// AddFail 添加失败 func (r *GoodsImportResult) AddFail(detail string) { r.FailCount++ r.FailDetails = append(r.FailDetails, detail) diff --git a/models/request/product.go b/models/request/product.go index d951adc..d8e2d6c 100644 --- a/models/request/product.go +++ b/models/request/product.go @@ -168,6 +168,12 @@ type GetProductDetailRequest struct { ID int64 `form:"id" binding:"required"` } +// GetProductFullInfoRequest 获取商品完整信息请求(无需签名) +type GetProductFullInfoRequest struct { + ProductID int64 `form:"product_id" binding:"required"` // 商品ID + UserID int64 `form:"user_id" binding:"required"` // 用户ID +} + // PushProductToShopRequest 上架到商铺请求 type PushProductToShopRequest struct { UserID int64 `form:"user_id" json:"user_id" binding:"required"` // 用户ID(租户) diff --git a/models/response/product.go b/models/response/product.go index 0de73d7..637c47b 100644 --- a/models/response/product.go +++ b/models/response/product.go @@ -211,3 +211,36 @@ type ProductInventoryWarehouse struct { Appearance int64 `json:"appearance"` // 品相 TotalQuantity int64 `json:"total_quantity"` // 该仓库下该商品的总库存 } + +// ProductFullInfoResponse 商品完整信息响应 +type ProductFullInfoResponse struct { + ID int64 `json:"id"` // 商品ID + CategoryID int64 `json:"category_id"` // 分类ID + CategoryName string `json:"category_name"` // 分类名称 + StandardProductID int64 `json:"standard_product_id"` // 标准商品ID + Name string `json:"name"` // 商品名称 + Appearance int64 `json:"appearance"` // 外观/品相 + Barcode string `json:"barcode"` // 条码 + Price int64 `json:"price"` // 价格(分) + SalePrice int64 `json:"sale_price"` // 售价(分) + LiveImage []string `json:"live_image"` // 实拍图 + IsBatchManaged int8 `json:"is_batch_managed"` // 是否批次管理 + IsShelfLifeManaged int8 `json:"is_shelf_life_managed"` // 是否保质期管理 + Status int8 `json:"status"` // 状态 + CreatedAt int64 `json:"created_at"` // 创建时间 + UpdatedAt int64 `json:"updated_at"` // 更新时间 + Inventories []ProductInventoryDetail `json:"inventories"` // 库存详情列表 + ShopList []ShopInfo `json:"shop_list"` // 店铺信息列表 +} + +// ProductInventoryDetail 库存详情 +type ProductInventoryDetail struct { + WarehouseID int64 `json:"warehouse_id"` // 仓库ID + WarehouseName string `json:"warehouse_name"` // 仓库名称 + WarehouseCode string `json:"warehouse_code"` // 仓库编码 + LocationID int64 `json:"location_id"` // 库位ID + LocationCode string `json:"location_code"` // 库位编码 + LocationName string `json:"location_name"` // 库位名称 + Quantity int64 `json:"quantity"` // 库存数量 + InboundTime string `json:"inbound_time"` // 入库时间 +} diff --git a/routes/routes.go b/routes/routes.go index 8705cc5..0e64b43 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -85,7 +85,8 @@ func initRouter() (r *gin.Engine) { public.GET("/product_book/detail", productBookApi.Detail) // 获取商品反射详情 public.POST("/product_book/create", productBookApi.Create) // 创建商品反射 public.POST("/product_book/update", productBookApi.Update) // 更新商品反射 - public.GET("/product_book/del", productBookApi.Del) // 删除商品反射 + public.GET("/product_book/del", productBookApi.Del) + public.GET("/product/full_info", productApi.GetProductFullInfo) // 删除商品反射 } diff --git a/service/car.go b/service/car.go index 4f32b14..2d48021 100644 --- a/service/car.go +++ b/service/car.go @@ -15,6 +15,7 @@ import ( type CarService struct{} +// GetCarList 获取小车列表 func (s *CarService) GetCarList(req systemReq.QueryCarRequest, db ...*gorm.DB) ([]systemRes.CarResponse, int64, error) { databaseConn := database.OptionalDB(db...) @@ -66,6 +67,7 @@ func (s *CarService) GetCarList(req systemReq.QueryCarRequest, db ...*gorm.DB) ( return responses, total, nil } +// GetCarByID 获取小车信息 func (s *CarService) GetCarByID(id int64, db ...*gorm.DB) (*systemRes.CarResponse, error) { databaseConn := database.OptionalDB(db...) @@ -96,6 +98,7 @@ func (s *CarService) GetCarByID(id int64, db ...*gorm.DB) (*systemRes.CarRespons return &resp, nil } +// CreateCar 创建小车 func (s *CarService) CreateCar(req systemReq.CreateCarRequest, id int64, db ...*gorm.DB) (int64, error) { databaseConn := database.OptionalDB(db...) @@ -139,6 +142,7 @@ func (s *CarService) CreateCar(req systemReq.CreateCarRequest, id int64, db ...* return car.ID, nil } +// UpdateCar 修改小车 func (s *CarService) UpdateCar(req systemReq.UpdateCarRequest, id int64, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) @@ -187,6 +191,7 @@ func (s *CarService) UpdateCar(req systemReq.UpdateCarRequest, id int64, db ...* return nil } +// DeleteCar 删除小车 func (s *CarService) DeleteCar(id int64, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) diff --git a/service/employee.go b/service/employee.go index 1c75358..cf2317f 100644 --- a/service/employee.go +++ b/service/employee.go @@ -978,7 +978,7 @@ func (s *EmployeeService) createEmployeeLevelLog(empId int64, operationType int8 PageSize: req.PageSize, }, nil }*/ - +// GetUserList 获取用户列表(从从库) func (s *EmployeeService) GetUserList(req systemReq.GetUserListRequest) (*systemRes.GetUserListResponse, error) { if req.Page < 1 { req.Page = 1 diff --git a/service/location.go b/service/location.go index d4edeb3..341c0b9 100644 --- a/service/location.go +++ b/service/location.go @@ -18,6 +18,7 @@ import ( type LocationService struct{} +// GetLocationList 获取库位列表 func (s *LocationService) GetLocationList(req systemReq.QueryLocationRequest, db ...*gorm.DB) ([]systemRes.LocationResponse, int64, error) { databaseConn := database.OptionalDB(db...) @@ -112,6 +113,7 @@ func (s *LocationService) GetAllLocationList(req systemReq.QueryAllLocationReque return responses, total, nil } +// GetLocationDetail 获取库位详情 func (s *LocationService) GetLocationDetail(id int64, db ...*gorm.DB) (*systemRes.LocationResponse, error) { databaseConn := database.OptionalDB(db...) @@ -127,6 +129,7 @@ func (s *LocationService) GetLocationDetail(id int64, db ...*gorm.DB) (*systemRe return &resp, nil } +// GetLocationInfo 获取库位信息 func (s *LocationService) GetLocationInfo(code, warehouseCode string, db ...*gorm.DB) (*systemRes.LocationResponse, error) { databaseConn := database.OptionalDB(db...) @@ -150,6 +153,7 @@ func (s *LocationService) GetLocationInfo(code, warehouseCode string, db ...*gor return &resp, nil } +// CreateLocation 创建库位 func (s *LocationService) CreateLocation(req systemReq.CreateLocationRequest, db ...*gorm.DB) (int64, error) { databaseConn := database.OptionalDB(db...) @@ -204,6 +208,7 @@ func (s *LocationService) CreateLocation(req systemReq.CreateLocationRequest, db } } +// UpdateLocation 修改库位 func (s *LocationService) BatchGenerateLocations(req systemReq.BatchGenerateLocationRequest, db ...*gorm.DB) (*systemRes.BatchGenerateResult, error) { databaseConn := database.OptionalDB(db...) @@ -330,6 +335,7 @@ func (s *LocationService) BatchGenerateLocations(req systemReq.BatchGenerateLoca return result, nil } +// UpdateLocation 修改库位 func (s *LocationService) UpdateLocation(req systemReq.UpdateLocationRequest, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) @@ -407,6 +413,7 @@ func (s *LocationService) UpdateLocation(req systemReq.UpdateLocationRequest, db return nil } +// DeleteLocation 删除库位 func (s *LocationService) DeleteLocation(ids []int64, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) @@ -430,6 +437,7 @@ func (s *LocationService) DeleteLocation(ids []int64, db ...*gorm.DB) error { return nil } +// GetLocationList 获取库位列表 // SyncLocations 同步库位数据(包含物流模板、仓库、货区) func (s *LocationService) SyncLocations(req systemReq.SyncLocationRequest) (*systemRes.SyncLocationResponse, error) { databaseConn, err := database.GetTenantDB(req.UserID) @@ -522,6 +530,7 @@ func (s *LocationService) SyncLocations(req systemReq.SyncLocationRequest) (*sys return result, nil } +// createOrUpdateLogistics 创建或更新物流模板 func (s *LocationService) createOrUpdateLogistics(tx *gorm.DB, logisticsReq systemReq.SyncLogisticsRequest, userID int64, now int64) (int64, error) { var logistics models.Logistics @@ -598,6 +607,7 @@ func (s *LocationService) createOrUpdateLogistics(tx *gorm.DB, logisticsReq syst } } +// createOrUpdateWarehouse 创建或更新仓库 func (s *LocationService) createOrUpdateWarehouse(tx *gorm.DB, area systemReq.SyncLocationAreaRequest, logisticsID int64, userID int64, now int64) (int64, error) { var warehouse models.Warehouse @@ -647,6 +657,7 @@ func (s *LocationService) createOrUpdateWarehouse(tx *gorm.DB, area systemReq.Sy } } +// batchCreateLocations 批量创建库位 func (s *LocationService) batchCreateLocations(tx *gorm.DB, warehouseID int64, items []systemReq.SyncLocationItemRequest, now int64) (*systemRes.SyncLocationResponse, error) { result := &systemRes.SyncLocationResponse{ SuccessCodes: make([]string, 0), @@ -740,6 +751,7 @@ func (s *LocationService) batchCreateLocations(tx *gorm.DB, warehouseID int64, i return result, nil } +// createOrUpdateLocation 创建或更新库位 // SyncGoods 同步商品数据并创建库存 func (s *LocationService) SyncGoods(req systemReq.SyncGoodsRequest) (*systemRes.SyncGoodsResponse, error) { databaseConn, err := database.GetTenantDB(req.UserID) @@ -922,6 +934,7 @@ func (s *LocationService) parseAppearance(appearance string) int64 { return result } +// generateLevelValues 生成层级值 func generateLevelValues(config systemReq.GroupConfig) ([]string, error) { values := make([]string, 0) @@ -1094,6 +1107,7 @@ func generateLevelValues(config systemReq.GroupConfig) ([]string, error) { return values, nil } +// charToNum 将字符转换为数字 func charToNum(c byte) int { if c >= 'A' && c <= 'Z' { return int(c - 'A') @@ -1104,6 +1118,7 @@ func charToNum(c byte) int { return -1 } +// numToChar 将数字转换为字符 func numToChar(n int) byte { if n >= 0 && n < 26 { return byte('A' + n) diff --git a/service/logistics.go b/service/logistics.go index 4517cc2..65870a4 100644 --- a/service/logistics.go +++ b/service/logistics.go @@ -16,6 +16,7 @@ import ( type LogisticsService struct{} +// GetLogisticsList 获取物流模板列表 func (s *LogisticsService) GetLogisticsList(req request.QueryLogisticsRequest, db ...*gorm.DB) ([]response.LogisticsResponse, int64, error) { databaseConn := database.OptionalDB(db...) @@ -61,6 +62,7 @@ func (s *LogisticsService) GetLogisticsList(req request.QueryLogisticsRequest, d return responses, total, nil } +// GetLogisticsByID 获取物流模板详情 func (s *LogisticsService) GetLogisticsByID(id uint64, db ...*gorm.DB) (*response.LogisticsResponse, error) { databaseConn := database.OptionalDB(db...) @@ -76,6 +78,7 @@ func (s *LogisticsService) GetLogisticsByID(id uint64, db ...*gorm.DB) (*respons return &resp, nil } +// CreateLogistics 创建物流模板 // calculateMinFirstFee 从 shipping_range JSON 中计算最小首费 func (s *LogisticsService) calculateMinFirstFee(shippingRange string) (float64, error) { if shippingRange == "" { @@ -123,6 +126,7 @@ func (s *LogisticsService) calculateMinFirstFee(shippingRange string) (float64, return minFee, nil } +// CreateLogistics 创建物流模板 func (s *LogisticsService) CreateLogistics(req request.CreateLogisticsRequest, db ...*gorm.DB) (uint64, error) { databaseConn := database.OptionalDB(db...) @@ -176,6 +180,7 @@ func (s *LogisticsService) CreateLogistics(req request.CreateLogisticsRequest, d return logistics.Id, nil } +// UpdateLogistics 修改物流模板 func (s *LogisticsService) UpdateLogistics(req request.UpdateLogisticsRequest, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) @@ -231,6 +236,7 @@ func (s *LogisticsService) UpdateLogistics(req request.UpdateLogisticsRequest, d return nil } +// DeleteLogistics 删除物流模板 func (s *LogisticsService) DeleteLogistics(id uint64, db ...*gorm.DB) error { databaseConn := database.OptionalDB(db...) diff --git a/service/ocr.go b/service/ocr.go index 9231a9a..bbc7758 100644 --- a/service/ocr.go +++ b/service/ocr.go @@ -25,6 +25,7 @@ type ocrServiceResponse struct { Texts []string `json:"texts,omitempty"` } +// RecognizeText 调用OCR服务进行文字识别 func (s *OcrService) RecognizeText(imageData []byte) (systemRes.OcrResponse, error) { base64Data := base64.StdEncoding.EncodeToString(imageData) @@ -72,6 +73,7 @@ type candidate struct { index int } +// analyzeBookInfo 分析识别结果 func (s *OcrService) analyzeBookInfo(texts []string) systemRes.GuessBookInfo { var result systemRes.GuessBookInfo @@ -120,6 +122,7 @@ func (s *OcrService) analyzeBookInfo(texts []string) systemRes.GuessBookInfo { return result } +// isBookName 判断给定的文本是否可能是图书名称 func (s *OcrService) isBookName(text string) bool { if len(text) < 2 || len(text) > 30 { return false @@ -218,6 +221,7 @@ func (s *OcrService) isBookName(text string) bool { return true } +// calculateBookNameScore 计算图书名称的得分 func (s *OcrService) extractAuthor(text string) string { if s.hasAuthorMarker(text) { cleaned := s.removeAuthorMarker(text) @@ -273,6 +277,7 @@ func (s *OcrService) extractAuthor(text string) string { return "" } +// extractPublisher 提取出版商 func (s *OcrService) extractPublisher(text string) string { publisherKeywords := []string{ "出版社", "出版", "press", "Publishing", @@ -287,6 +292,7 @@ func (s *OcrService) extractPublisher(text string) string { return "" } +// hasAuthorMarker 检测给定的文本是否包含作者标记 func (s *OcrService) hasAuthorMarker(text string) bool { markers := []string{"著", "编", "作者", "/", "·"} for _, marker := range markers { @@ -297,6 +303,7 @@ func (s *OcrService) hasAuthorMarker(text string) bool { return false } +// hasPublisherMarker 检测给定的文本是否包含出版商标记 func (s *OcrService) hasPublisherMarker(text string) bool { markers := []string{"出版社", "出版", "press", "Publishing"} textLower := strings.ToLower(text) @@ -332,6 +339,7 @@ func (s *OcrService) hasPublisherMarker(text string) bool { return false } +// removeAuthorMarker 移除作者标记 func (s *OcrService) removeAuthorMarker(text string) string { result := text @@ -353,6 +361,7 @@ func (s *OcrService) removeAuthorMarker(text string) string { return strings.TrimSpace(result) } +// calculateBookNameScore 计算图书名称的得分 func (s *OcrService) calculateBookNameScore(text string) int { score := 0 @@ -385,6 +394,7 @@ func (s *OcrService) calculateBookNameScore(text string) int { return score } +// calculateAuthorScore 计算作者的得分 func (s *OcrService) calculateAuthorScore(author, originalText string) int { score := 0 @@ -415,6 +425,7 @@ func (s *OcrService) calculateAuthorScore(author, originalText string) int { return score } +// calculatePublisherScore 检测给定的文本是否包含出版商标记 func (s *OcrService) calculatePublisherScore(text string) int { score := 0 @@ -431,6 +442,7 @@ func (s *OcrService) calculatePublisherScore(text string) int { return score } +// selectBestCandidate 选择最佳候选项 func (s *OcrService) selectBestCandidate(candidates []candidate) candidate { if len(candidates) == 0 { return candidate{} diff --git a/service/out_task.go b/service/out_task.go index ceaa016..5a89853 100644 --- a/service/out_task.go +++ b/service/out_task.go @@ -275,6 +275,7 @@ func (s *OutTaskService) GetOutTaskByShop(req systemReq.GetOutTaskByShopRequest, }, nil } +// UpdateOutTaskLog 更新外部任务日志 func (s *OutTaskService) UpdateOutTaskLog(req systemReq.UpdateOutTaskLogRequest) error { databaseConn, err := database.GetTenantDB(req.UserID) if err != nil { diff --git a/service/process.go b/service/process.go index 6a95e36..6f78be8 100644 --- a/service/process.go +++ b/service/process.go @@ -1362,6 +1362,7 @@ func (s *ProcessService) GetReceivingDetail(receivingOrderID int64, db ...*gorm. return result, nil } +// CreateSalesOrderWithDetail 创建销售订单(事务内) func (s *ProcessService) CreateSalesOrderWithDetail(req systemReq.SalesOrderCreateRequest) (int64, error) { databaseConn, err := database.GetTenantDB(req.AboutId) if err != nil { @@ -4125,6 +4126,7 @@ func (s *ProcessService) syncProductsToExternal(receivingOrderID, waveTaskID, us return nil } +// saveOutTaskLog 保存外部任务日志 func (s *ProcessService) saveOutTaskLog(outTask models.OutTask, bodyList []models.OutTaskLog, msg string, db *gorm.DB) { now := time.Now().Unix() for _, body := range bodyList { diff --git a/service/product.go b/service/product.go index 8e07bfc..5174762 100644 --- a/service/product.go +++ b/service/product.go @@ -29,6 +29,7 @@ type OutTaskInfo struct { ShopList []systemRes.ShopInfo } +// 获取商品列表 func (s *ProductService) GetProductList(req systemReq.GetProductListRequest, db ...*gorm.DB) (*systemRes.ProductListResponse, error) { databaseConn := database.OptionalDB(db...) @@ -129,6 +130,7 @@ func (s *ProductService) GetProductList(req systemReq.GetProductListRequest, db }, nil } +// 获取商品任务信息 func (s *ProductService) GetDistributionProductList(req systemReq.GetDistributionProductListRequest) (*systemRes.ProductListResponse, error) { databaseConn, err := database.GetTenantDB(req.UserID) if err != nil { @@ -287,6 +289,127 @@ func (s *ProductService) GetProductDetail(req systemReq.GetProductDetailRequest, return item, nil } +// GetProductFullInfo 获取商品完整信息(包含库存和店铺信息) +func (s *ProductService) GetProductFullInfo(req systemReq.GetProductFullInfoRequest, db ...*gorm.DB) (*systemRes.ProductFullInfoResponse, error) { + databaseConn := database.OptionalDB(db...) + + utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "开始查询商品完整信息", + "product_id": req.ProductID, + "user_id": req.UserID, + }) + + if req.ProductID <= 0 { + return nil, utils.NewError("商品ID不能为空") + } + + if req.UserID <= 0 { + return nil, utils.NewError("用户ID不能为空") + } + + var product models.Product + if err := databaseConn.Where("id = ? AND is_del = ?", req.ProductID, 0).First(&product).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "商品不存在", + "product_id": req.ProductID, + }) + return nil, utils.NewError("商品不存在") + } + utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "查询商品失败", + "product_id": req.ProductID, + "error": err.Error(), + }) + return nil, utils.NewError("查询商品失败") + } + + utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "商品基本信息查询成功", + "product_name": product.Name, + "barcode": product.Barcode, + }) + + var liveImage []string + if len(product.LiveImage) > 0 { + if err := json.Unmarshal(product.LiveImage, &liveImage); err != nil { + utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "解析商品图片失败", + "error": err.Error(), + }) + liveImage = []string{} + } + } + + var categoryName string + if product.CategoryID > 0 { + var category models.ProductCategory + if err := databaseConn.Where("id = ?", product.CategoryID).First(&category).Error; err == nil { + categoryName = category.Name + } + } + + var inventories []systemRes.ProductInventoryDetail + if err := databaseConn.Table("inventory_detail inv"). + Select("inv.warehouse_id, w.name as warehouse_name, w.code as warehouse_code, inv.location_id, l.code as location_code, l.name as location_name, inv.quantity, inv.inbound_time"). + Joins("LEFT JOIN warehouse w ON w.id = inv.warehouse_id"). + Joins("LEFT JOIN location l ON l.id = inv.location_id"). + Where("inv.product_id = ? AND inv.is_del = ?", req.ProductID, 0). + Scan(&inventories).Error; err != nil { + utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "查询库存信息失败", + "error": err.Error(), + }) + inventories = []systemRes.ProductInventoryDetail{} + } + + utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "库存信息查询完成", + "inventory_count": len(inventories), + }) + + outTaskInfoMap, err := s.getProductOutTaskInfo(databaseConn, []int64{req.ProductID}) + if err != nil { + utils.ErrorLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "查询任务信息失败", + "error": err.Error(), + }) + } + + var shopList []systemRes.ShopInfo + if outTaskInfo, exists := outTaskInfoMap[req.ProductID]; exists { + shopList = outTaskInfo.ShopList + } + + response := &systemRes.ProductFullInfoResponse{ + ID: product.ID, + CategoryID: product.CategoryID, + CategoryName: categoryName, + StandardProductID: product.StandardProductID, + Name: product.Name, + Appearance: product.Appearance, + Barcode: product.Barcode, + Price: product.Price, + SalePrice: product.SalePrice, + LiveImage: liveImage, + IsBatchManaged: product.IsBatchManaged, + IsShelfLifeManaged: product.IsShelfLifeManaged, + Status: product.Status, + CreatedAt: product.CreatedAt, + UpdatedAt: product.UpdatedAt, + Inventories: inventories, + ShopList: shopList, + } + + utils.InfoLog(constant.LoggerChannelWork, map[string]interface{}{ + "action": "商品完整信息查询成功", + "success": true, + "shop_count": len(shopList), + }) + + return response, nil +} + // getProductOutTaskInfo func (s *ProductService) getProductOutTaskInfo(db *gorm.DB, productIDs []int64) (map[int64]*OutTaskInfo, error) { resultMap := make(map[int64]*OutTaskInfo) @@ -2263,6 +2386,7 @@ func (s *ProductService) createProductLog(req systemReq.ProductLogRequest, now, return product.ID, nil } +// 更新商品日志 func (s *ProductService) updateProductLog(req systemReq.ProductLogRequest, now int64) (int64, error) { var productLog models.ProductLog if err := database.DB.Where("id = ? AND is_del = 0", req.ID).First(&productLog).Error; err != nil { @@ -2355,6 +2479,7 @@ func (s *ProductService) updateProductLog(req systemReq.ProductLogRequest, now i return productLog.ID, nil } +// 审核商品日志 func (s *ProductService) AuditProductLog(req systemReq.AuditProductLogRequest, userID int64) error { var log models.ProductLog if err := database.DB.Where("id = ? AND is_del = 0", req.ID).First(&log).Error; err != nil { @@ -2458,6 +2583,7 @@ func (s *ProductService) syncApprovedLogToES(barcode string, req systemReq.Audit return nil } +// 删除商品日志 func (s *ProductService) DeleteProductLog(req systemReq.DeleteProductLogRequest) error { var log models.ProductLog if err := database.DB.Where("id = ? AND is_del = 0", req.ID).First(&log).Error; err != nil { diff --git a/service/shop.go b/service/shop.go index 08a3f21..70aa5a3 100644 --- a/service/shop.go +++ b/service/shop.go @@ -12,6 +12,7 @@ import ( type ShopService struct{} +// GetShopList 获取店铺列表 func (s *ShopService) GetShopList(req systemReq.QueryShopRequest, db ...*gorm.DB) ([]systemRes.ShopResponse, int64, error) { databaseConn := database.OptionalDB(db...)