最新版本

This commit is contained in:
Administrator 2026-06-18 13:01:56 +08:00
parent 5308b4f069
commit 96c39486af
26 changed files with 326 additions and 6 deletions

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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

View File

@ -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")

View File

@ -68,6 +68,7 @@ func (r *LocationApi) GetAllLocationList(c *gin.Context) {
})
}
// GetLocationDetail 获取库位详情
func (r *LocationApi) GetLocationDetail(c *gin.Context) {
idStr := c.Param("id")

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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{

View File

@ -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 {

View File

@ -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 {

View File

@ -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"` // 物流单号
}

View File

@ -28,6 +28,7 @@ type GoodsImportResult struct {
Message string
}
// AddFail 添加失败
func (r *GoodsImportResult) AddFail(detail string) {
r.FailCount++
r.FailDetails = append(r.FailDetails, detail)

View File

@ -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(租户)

View File

@ -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"` // 入库时间
}

View File

@ -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) // 删除商品反射
}

View File

@ -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...)

View File

@ -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

View File

@ -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)

View File

@ -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...)

View File

@ -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{}

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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...)