diff --git a/app/admin/apis/basic/commodity.go b/app/admin/apis/basic/commodity.go index ccd7cd1..af3e3ed 100644 --- a/app/admin/apis/basic/commodity.go +++ b/app/admin/apis/basic/commodity.go @@ -15,7 +15,8 @@ import ( type CommodityCreateRequest struct { Name string `json:"name" binding:"required"` // 商品名称 ErpCategoryId uint32 `json:"erp_category_id" binding:"required"` // 商品分类id - IMEIType uint32 `json:"imei_type" binding:"required"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) + IsIMEI uint32 `json:"is_imei" binding:"required"` // 是否串码:1-串码类 2-非串码 + IMEIType uint32 `json:"imei_type" binding:"required"` // 系统生成串码:2-是(系统生成) 3-否(手动添加) ErpSupplierId uint32 `json:"erp_supplier_id" binding:"required"` // 主供应商 RetailPrice uint32 `json:"retail_price" binding:"required"` // 指导零售价 MinRetailPrice uint32 `json:"min_retail_price" binding:"required"` // 最低零售价 @@ -68,6 +69,10 @@ func CommodityCreate(c *gin.Context) { return } + if req.IsIMEI == 2 { // 是否串码:1-串码类 2-非串码 + req.IMEIType = 1 // 系统生成串码:2-是(系统生成) 3-否(手动添加) 1表示非串码 + } + commodity := &models.ErpCommodity{ Number: 1, Name: req.Name, @@ -175,6 +180,12 @@ func CommodityDetail(c *gin.Context) { return } + if commodity.IMEIType == 1 { //无串码 + commodity.IsIMEI = 2 // 非串码 + } else { + commodity.IsIMEI = 1 // 串码 + } + app.OK(c, commodity, "") return } diff --git a/app/admin/apis/inventorymanage/Inventory.go b/app/admin/apis/inventorymanage/Inventory.go index bb2d5a3..1cf452e 100644 --- a/app/admin/apis/inventorymanage/Inventory.go +++ b/app/admin/apis/inventorymanage/Inventory.go @@ -11,6 +11,16 @@ import ( "net/http" ) +type DeliveryCargoReq struct { + Id uint32 `json:"id" binding:"required"` // 商品库存列表id + State uint32 `json:"state" binding:"required"` // 库存状态:4-出库 +} + +type AddRemarkReq struct { + Id int `json:"id" binding:"required"` // 商品库存列表id + Remark string `json:"remark"` // 备注 +} + // GetInventoryList 查询库存列表 // @Summary 查询库存列表 // @Tags 库存管理 @@ -65,11 +75,6 @@ func GetInventoryDetail(c *gin.Context) { return } -type DeliveryCargoReq struct { - Id uint32 `json:"id" binding:"required"` // 商品库存列表id - State uint32 `json:"state" binding:"required"` // 库存状态:4-出库 -} - // DeliveryCargo 出库 // @Summary 出库 // @Tags 库存管理 @@ -142,125 +147,6 @@ func BatchPrint(c *gin.Context) { // @Param file body string true "上传excel文件" // @Success 200 {object} app.Response // @Router /api/v1/inventory/import [post] -//func BatchImport(c *gin.Context) { -// models.EsStockLock.Lock() -// defer models.EsStockLock.Unlock() -// -// file, header, err := c.Request.FormFile("file") -// if err != nil { -// //logger.Error("form file err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// defer file.Close() -// -// readAll, err := io.ReadAll(file) -// if err != nil { -// //logger.Error("read all err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// fmt.Println("header:", header.Filename) -// //fmt.Println("readAll:", readAll) -// -// fileStart := time.Now().UnixMilli() -// bCol, colsMap, err := models.FileExcelImport(readAll, nil, 3) -// if err != nil { -// //logger.Error("file excel reader err:", err) -// app.Error(c, http.StatusInternalServerError, err, err.Error()) -// return -// } -// fmt.Println("FileExcelReader", time.Now().UnixMilli()-fileStart) -// fmt.Println("colsMap:", colsMap) -// if len(colsMap) != 0 { -// colsMap = colsMap[1:] -// } -// -// var stockFiles []models.StockExcel -// err = json.Unmarshal(bCol, &stockFiles) -// if err != nil { -// //logger.Error("erp commodity file excel unmarshal err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// if len(stockFiles) != 0 { -// stockFiles = stockFiles[1:] -// } -// stockier := models.NewStockImporter() -// fileStart = time.Now().UnixMilli() -// erpStocks := make([]models.ErpStockCommodity, 0, len(stockFiles)) -// erpStocks, err = stockier.ImportStockData(stockFiles) -// if err != nil { -// //logger.Error("processing err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// fmt.Println("ErpStockFileExcelListProcessing", time.Now().UnixMilli()-fileStart) -// -// begin := orm.Eloquent.Begin() -// total := len(erpStocks) -// size := 200 -// page := total / size -// if total%size != 0 { -// page += 1 -// } -// errGroup := errgroup.Group{} -// for i := 0; i < page; i++ { -// if i == page-1 { -// stockList := erpStocks[i*size:] -// err = begin.Create(&stockList).Error -// if err != nil { -// begin.Rollback() -// //logger.Error("create commodity err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// } else { -// errGroup.Go(func() error { -// stockList := erpStocks[i*size : (i+1)*size] -// err = begin.Create(&stockList).Error -// if err != nil { -// begin.Rollback() -// //logger.Error("create commodity err:", err) -// return err -// } -// return nil -// }) -// } -// } -// err = stockier.ErpStockCountUpdate(begin) -// if err != nil { -// begin.Rollback() -// //logger.Error("erp stock count update err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// -// err = errGroup.Wait() -// if err != nil { -// begin.Rollback() -// //logger.Error("err group wait err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// err = begin.Commit().Error -// if err != nil { -// begin.Rollback() -// //logger.Error("commit err:", err) -// app.Error(c, http.StatusInternalServerError, err, "导入失败") -// return -// } -// -// logging := models.Logging{ -// Function: "库存导入", -// Event: models.LoggingEventInventoryImport, -// EventName: "库存导入", -// } -// logging.Create(c) -// app.OK(c, nil, "OK") -// return -//} - func BatchImport(c *gin.Context) { models.EsStockLock.Lock() defer models.EsStockLock.Unlock() @@ -280,7 +166,6 @@ func BatchImport(c *gin.Context) { } fmt.Println("header:", header.Filename) - _, colsMap, err := models.FileExcelImport(readAll, nil, 3) if err != nil { //logger.Error("file excel reader err:", err) @@ -294,7 +179,7 @@ func BatchImport(c *gin.Context) { } stockier := models.NewStockImporter() - err = stockier.ImportStockData2(colsMap) + err = stockier.ImportStockData(colsMap) if err != nil { app.Error(c, http.StatusInternalServerError, err, err.Error()) return @@ -303,3 +188,35 @@ func BatchImport(c *gin.Context) { app.OK(c, nil, "导入成功") return } + +// AddRemark 添加备注 +// @Summary 添加备注 +// @Tags 库存管理 +// @Produce json +// @Accept json +// @Param request body AddRemarkReq true "添加备注模型" +// @Success 200 {object} app.Response +// @Router /api/v1/inventory/add_remark [post] +func AddRemark(c *gin.Context) { + req := &AddRemarkReq{} + if err := c.ShouldBindJSON(&req); err != nil { + //logger.Error(err) + app.Error(c, http.StatusBadRequest, errors.New("param err"), "参数错误") + return + } + + if err := tools.Validate(req); err != nil { + app.Error(c, http.StatusBadRequest, err, err.Error()) + return + } + + err := models.UpdateStockCommodityRemark(req.Id, req.Remark) + if err != nil { + //logger.Error("erp stock err:", err) + app.Error(c, http.StatusInternalServerError, err, "获取失败") + return + } + + app.OK(c, nil, "OK") + return +} diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index 4bcac9d..e7da0ee 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -65,7 +65,7 @@ type ErpStockCommodity struct { StockEndTime time.Time `json:"stock_end_time" gorm:"-"` // 最近入库结束时间 Age uint32 `json:"age" gorm:"-"` // 最近库龄 AllAge uint32 `json:"all_age" gorm:"-"` // 总库龄 - Remark string `json:"remark" gorm:"-"` // 备注 + Remark string `json:"remark"` // 备注 //Commodity ErpCommodity `json:"commodity" gorm:"-"` } @@ -78,6 +78,7 @@ type ErpCommodity struct { Name string `json:"name"` // 商品名称 ErpCategoryId uint32 `json:"erp_category_id" gorm:"index"` // 商品分类id ErpCategoryName string `json:"erp_category_name"` // 商品分类名称 + IsIMEI uint32 `json:"is_imei" gorm:"-"` // 是否串码:1-串码类 2-非串码 IMEIType uint32 `json:"imei_type"` // 1-无串码 2-串码(系统生成) 3-串码(手动添加) IMEI string `json:"imei"` // 串码 ErpSupplierId uint32 `json:"erp_supplier_id" gorm:"index"` // 主供应商id @@ -319,6 +320,14 @@ func (m *ErpCommodityListReq) List() (*ErpCommodityListResp, error) { resp.List = commodities } + for i, v := range resp.List { + if v.IMEIType == 1 { //无串码 + resp.List[i].IsIMEI = 2 // 非串码 + } else { + resp.List[i].IsIMEI = 1 // 串码 + } + } + return resp, nil } @@ -430,94 +439,6 @@ func (m *ErpCategoryListReq) List() (*ErpCategoryListResp, error) { return resp, nil } -var ErpCommodityFileExcelCols = []string{"category_1", "category_2", "name", "is_imei", "erp_supplier_name", - "brokerage_1_string", "brokerage_2_string", "retail_price_string", "min_retail_price_string", - "staff_cost_price_string", "wholesale_price_string", "origin", "remark"} - -type ErpCommodityFileExcel struct { - Category1 string `json:"category_1"` - Category2 string `json:"category_2"` - IsIMEI string `json:"is_imei"` - - RetailPriceString string `json:"retail_price_string"` - MinRetailPriceString string `json:"min_retail_price_string"` - StaffCostPriceString string `json:"staff_cost_price_string"` - WholesalePriceString string `json:"wholesale_price_string"` - Brokerage1String string `json:"brokerage_1_string"` - Brokerage2String string `json:"brokerage_2_string"` - - Code string `json:"code"` - ErpCommodity -} - -func (e *ErpCommodityFileExcel) Processing() { - if e.IsIMEI == "是" { - e.IMEIType = 2 - } else if e.IsIMEI == "否" { - e.IMEIType = 1 - } - - e.RetailPrice = PercentFloatStringToUin32(e.RetailPriceString) - e.MinRetailPrice = PercentFloatStringToUin32(e.MinRetailPriceString) - e.StaffCostPrice = PercentFloatStringToUin32(e.StaffCostPriceString) - e.WholesalePrice = PercentFloatStringToUin32(e.WholesalePriceString) - e.Brokerage1 = PercentFloatStringToFloat(e.Brokerage1String) - e.Brokerage2 = PercentFloatStringToFloat(e.Brokerage2String) -} - -func PercentFloatStringToUin32(s string) uint32 { - u := uint32(0) - if s != "" { - s = strings.ReplaceAll(s, "%", "") - } - f, err := strconv.ParseFloat(s, 64) - if err != nil { - //logger.Error("parse float err:", err) - return u - } - - u = uint32(f * 100) - return u -} - -func PercentFloatStringToFloat(s string) float64 { - //u := uint32(0) - if s != "" { - s = strings.ReplaceAll(s, "%", "") - } - f, err := strconv.ParseFloat(s, 64) - if err != nil { - //logger.Error("parse float err:", err) - return f - } - - //u = uint32(f * 100) - return f -} - -func IntStringToUin32(s string) uint32 { - u := uint32(0) - if s != "" { - s = strings.ReplaceAll(s, "%", "") - } - i, err := strconv.Atoi(s) - if err != nil { - //logger.Error("parse float err:", err) - return u - } - - u = uint32(i) - return u -} - -type ErpCategorySub struct { - Id uint32 `json:"id"` - Name string `json:"name"` - FullNum uint32 `json:"full_num"` - SubMap map[string]ErpCategory - //UnCodeMap map[string]uint32 -} - type CommodityNumberCount struct { NumberMap map[uint32]uint32 `json:"number_map"` } @@ -539,15 +460,6 @@ func (m *CommodityNumberCount) GetErpCommodityNumberByCategoryId(categoryId uint return commodity.Number + 1, nil } -type ErpSupplierListResp struct { - List []ErpSupplier `json:"list"` - Total int `json:"total"` - PageNum int `json:"page_num"` - PageSize int `json:"page_size"` - ExportUrl string `json:"export_url"` -} - -var EsfLock sync.Mutex var EsStockLock sync.Mutex type StockImporter struct { @@ -604,7 +516,11 @@ func (e *ErpStockFileExcel) Processing() { } -func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error { +// ImportStockData 库存导入 +// 更新库存表和商品表 +// 库存表:插入对应的库存数据 +// 库存商品表:插入对应库存商品的数据;供应商只需判断是否在供应商列表即可 todo 库存商品表未插入库存id +func (m *StockImporter) ImportStockData(colsMap []map[string]interface{}) error { list, err := transStockData(colsMap) if err != nil { return err @@ -643,14 +559,12 @@ func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error //logger.Error("stores err:", err) return err } - var erpCommodities []ErpCommodity err = orm.Eloquent.Table("erp_commodity").Where("name IN (?)", erpCommodityNames).Find(&erpCommodities).Error if err != nil { //logger.Error("stores err:", err) return err } - var erpSuppliers []ErpSupplier err = orm.Eloquent.Table("erp_supplier").Debug().Where("name IN (?)", erpSupplierNames).Find(&erpSuppliers).Error if err != nil && !errors.Is(err, RecordNotFound) { @@ -662,31 +576,26 @@ func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error storeNameMap[stores[i].Name] = stores[i].ID m.StoreMap[stores[i].ID] = stores[i].Name } - for i, _ := range erpCommodities { erpCommodityMap[erpCommodities[i].Name] = &erpCommodities[i] m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i] } - for i, _ := range erpSuppliers { erpSupplierNameMap[erpSuppliers[i].Name] = erpSuppliers[i].ID } nowTime := time.Now() - //erpStockCommodity := make([]ErpStockCommodity, 0, len(list)) for i, _ := range list { v1, ok1 := storeNameMap[list[i].StoreName] if !ok1 { logger.Error("store name err") return errors.New("store name err") } - v2, ok2 := erpCommodityMap[list[i].Name] if !ok2 || v2 == nil { logger.Error("erp commodity name err") return errors.New("erp commodity name err") } - v3, ok3 := erpSupplierNameMap[list[i].SupplierName] if !ok3 { logger.Error("erp supplier name err") @@ -711,39 +620,40 @@ func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error return fmt.Errorf("数量转换有误:[%v]", err) } - stockCommodity := ErpStockCommodity{ - StoreId: v1, - StoreName: list[i].StoreName, - ErpCommodityId: v2.ID, - ErpCommodityName: v2.Name, - CommoditySerialNumber: list[i].SerialNum, - ErpCategoryId: v2.ErpCategoryId, - ErpCategoryName: v2.ErpCategoryName, - ErpSupplierId: v3, - ErpSupplierName: list[i].SupplierName, - StaffCostPrice: uint32(nStaffCostPrice - nWholesalePrice), - WholesalePrice: uint32(nWholesalePrice), - State: 1, - StorageType: 1, - FirstStockTime: nowTime, - StockTime: nowTime, - Count: uint32(nCount), - IMEIType: v2.IMEIType, - IMEI: v2.IMEI, - } + for j := 0; j < int(nCount); j++ { // 商品库存表都是单笔数据,如果非串码商品有多个,需要插入多条数据 + stockCommodity := ErpStockCommodity{ + StoreId: v1, + StoreName: list[i].StoreName, + ErpCommodityId: v2.ID, + ErpCommodityName: v2.Name, + CommoditySerialNumber: list[i].SerialNum, + ErpCategoryId: v2.ErpCategoryId, + ErpCategoryName: v2.ErpCategoryName, + ErpSupplierId: v3, + ErpSupplierName: list[i].SupplierName, + StaffCostPrice: uint32(nStaffCostPrice - nWholesalePrice), + WholesalePrice: uint32(nWholesalePrice), + State: 1, + StorageType: 1, + FirstStockTime: nowTime, + StockTime: nowTime, + Count: 1, + IMEIType: v2.IMEIType, + IMEI: v2.IMEI, + Remark: "", + } + if list[i].SysGenerate != "" { //导入串码不为空,则默认为3手动添加 + stockCommodity.IMEIType = 3 + stockCommodity.IMEI = list[i].SysGenerate + } + erpStockCommodity = append(erpStockCommodity, stockCommodity) - if list[i].SysGenerate != "" { //导入串码不为空,则默认为3手动添加 - stockCommodity.IMEIType = 3 - stockCommodity.IMEI = list[i].SysGenerate - } - - erpStockCommodity = append(erpStockCommodity, stockCommodity) - - _, ok4 := m.CensusMap[stockCommodity.StoreId] - if ok4 { - m.CensusMap[stockCommodity.StoreId][stockCommodity.ErpCommodityId] += stockCommodity.Count - } else { - m.CensusMap[stockCommodity.StoreId] = map[uint32]uint32{stockCommodity.ErpCommodityId: stockCommodity.Count} + _, ok4 := m.CensusMap[stockCommodity.StoreId] + if ok4 { + m.CensusMap[stockCommodity.StoreId][stockCommodity.ErpCommodityId] += stockCommodity.Count + } else { + m.CensusMap[stockCommodity.StoreId] = map[uint32]uint32{stockCommodity.ErpCommodityId: stockCommodity.Count} + } } } @@ -770,7 +680,6 @@ func (m *StockImporter) processErpStocks(erpStocks []ErpStockCommodity) error { } stockList := erpStocks[start:end] - errGroup.Go(func() error { return createStockList(begin, stockList) }) @@ -806,151 +715,6 @@ func createStockList(begin *gorm.DB, stockList []ErpStockCommodity) error { return nil } -// ImportStockData 库存导入 -// 更新库存表和商品表 -// 库存表:插入对应的库存数据() -// 库存商品表:插入对应库存商品的数据;供应商只需判断是否在供应商列表即可 -func (m *StockImporter) ImportStockData(list []StockExcel) ([]ErpStockCommodity, error) { - var erpStockCommodity []ErpStockCommodity - - storeNameMap := make(map[string]uint32, 0) - erpCommodityMap := make(map[string]*ErpCommodity, 0) - erpSupplierNameMap := make(map[string]uint32, 0) - - storeNames := make([]string, 0, len(list)) - erpCommodityNames := make([]string, 0, len(list)) - erpSupplierNames := make([]string, 0, len(list)) - - for i, _ := range list { - _, ok1 := storeNameMap[list[i].StoreName] - if !ok1 { - storeNames = append(storeNames, list[i].StoreName) - } - _, ok2 := erpCommodityMap[list[i].Name] - if !ok2 { - erpCommodityNames = append(erpCommodityNames, list[i].Name) - } - _, ok3 := erpSupplierNameMap[list[i].SupplierName] - if !ok3 { - erpSupplierNames = append(erpSupplierNames, list[i].SupplierName) - } - storeNameMap[list[i].StoreName] = uint32(0) - erpCommodityMap[list[i].Name] = nil - erpSupplierNameMap[list[i].SupplierName] = uint32(0) - } - - var stores []Store - err := orm.Eloquent.Table("store").Where("name IN (?)", storeNames).Find(&stores).Error - if err != nil { - //logger.Error("stores err:", err) - return nil, err - } - - var erpCommodities []ErpCommodity - err = orm.Eloquent.Table("erp_commodity").Where("name IN (?)", erpCommodityNames).Find(&erpCommodities).Error - if err != nil { - //logger.Error("stores err:", err) - return nil, err - } - - var erpSuppliers []ErpSupplier - err = orm.Eloquent.Table("erp_supplier").Debug().Where("name IN (?)", erpSupplierNames).Find(&erpSuppliers).Error - if err != nil && !errors.Is(err, RecordNotFound) { - //logger.Error("stores err:", err) - return nil, err - } - - for i, _ := range stores { - storeNameMap[stores[i].Name] = stores[i].ID - m.StoreMap[stores[i].ID] = stores[i].Name - } - - for i, _ := range erpCommodities { - erpCommodityMap[erpCommodities[i].Name] = &erpCommodities[i] - m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i] - } - - for i, _ := range erpSuppliers { - erpSupplierNameMap[erpSuppliers[i].Name] = erpSuppliers[i].ID - } - - nowTime := time.Now() - //erpStockCommodity := make([]ErpStockCommodity, 0, len(list)) - for i, _ := range list { - v1, ok1 := storeNameMap[list[i].StoreName] - if !ok1 { - logger.Error("store name err") - return nil, errors.New("store name err") - } - - v2, ok2 := erpCommodityMap[list[i].Name] - if !ok2 || v2 == nil { - logger.Error("erp commodity name err") - return nil, errors.New("erp commodity name err") - } - - v3, ok3 := erpSupplierNameMap[list[i].SupplierName] - if !ok3 { - logger.Error("erp supplier name err") - return nil, errors.New("erp supplier name err") - } - - // 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价 - nStaffCostPrice, err := strconv.ParseUint(list[i].StaffCostPrice, 10, 32) - if err != nil { - return nil, fmt.Errorf("员工成本价转换有误:[%v]", err) - } - nWholesalePrice, err := strconv.ParseUint(list[i].WholesalePrice, 10, 32) // 指导采购价 - if err != nil { - return nil, fmt.Errorf("指导采购价转换有误:[%v]", err) - } - if nStaffCostPrice < nWholesalePrice { - return nil, fmt.Errorf("导入价格有误,员工成本价低于指导采购价") - } - - nCount, err := strconv.ParseUint(list[i].Count, 10, 32) - if err != nil { - return nil, fmt.Errorf("数量转换有误:[%v]", err) - } - - stockCommodity := ErpStockCommodity{ - StoreId: v1, - StoreName: list[i].StoreName, - ErpCommodityId: v2.ID, - ErpCommodityName: v2.Name, - CommoditySerialNumber: list[i].SerialNum, - ErpCategoryId: v2.ErpCategoryId, - ErpCategoryName: v2.ErpCategoryName, - ErpSupplierId: v3, - ErpSupplierName: list[i].SupplierName, - StaffCostPrice: uint32(nStaffCostPrice - nWholesalePrice), - WholesalePrice: uint32(nWholesalePrice), - State: 1, - StorageType: 1, - FirstStockTime: nowTime, - StockTime: nowTime, - Count: uint32(nCount), - IMEIType: v2.IMEIType, - IMEI: v2.IMEI, - } - - if list[i].SysGenerate != "" { //导入串码不为空,则默认为3手动添加 - stockCommodity.IMEIType = 3 - stockCommodity.IMEI = list[i].SysGenerate - } - - erpStockCommodity = append(erpStockCommodity, stockCommodity) - - _, ok4 := m.CensusMap[stockCommodity.StoreId] - if ok4 { - m.CensusMap[stockCommodity.StoreId][stockCommodity.ErpCommodityId] += stockCommodity.Count - } else { - m.CensusMap[stockCommodity.StoreId] = map[uint32]uint32{stockCommodity.ErpCommodityId: stockCommodity.Count} - } - } - return erpStockCommodity, nil -} - func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error { for k1, v1 := range m.CensusMap { for k2, v2 := range v1 { @@ -1377,6 +1141,8 @@ type ErpStockCommodityListReq struct { PageSize int `json:"page_size"` // 页码 IsExport uint32 `json:"is_export"` // 是否导出excel:1-导出 } + +// ErpStockCommodityListResp 库存详情接口响应参数 type ErpStockCommodityListResp struct { List []ErpStockCommodity `json:"list"` Total int `json:"total"` @@ -1385,6 +1151,7 @@ type ErpStockCommodityListResp struct { ExportUrl string `json:"export_url"` } +// GetDetailList 查看库存详情 func (m *ErpStockCommodityListReq) GetDetailList() (*ErpStockCommodityListResp, error) { resp := &ErpStockCommodityListResp{ PageNum: m.PageNum, @@ -1467,6 +1234,10 @@ func (m *ErpStockCommodityListReq) buildQueryConditions(qs *gorm.DB) { qs = qs.Where("store_id=?", m.StoreId) } + if m.SupplierId != 0 { //供应商id + qs = qs.Where("supplier_id=?", m.SupplierId) + } + if m.State != 0 { //库存状态 qs = qs.Where("state=?", m.State) } @@ -1506,6 +1277,7 @@ func (m *ErpStockCommodityListReq) buildQueryConditions(qs *gorm.DB) { } } +// SetStockCommodityState 更新库存状态 func SetStockCommodityState(id, state uint32) error { if state != 4 { state = 4 @@ -1528,6 +1300,7 @@ type BatchPrintInfoReq struct { PrintListInfo []*BatchPrintInfo `json:"print_list_info" binding:"required"` } +// BatchPrint 批量打印标签 func BatchPrint(req *BatchPrintInfoReq) error { return nil @@ -1541,10 +1314,34 @@ func StringToFloat(req string) (float64, error) { return strconv.ParseFloat(req, 64) } -// 入库相关 -var ErpStockFileExcelCols = []string{"store_name", "erp_commodity_name", "erp_category_name", "serial_number", - "is_imei", "imei", "erp_supplier_name", "stock_time_string", "retail_price_string", - "min_retail_price_string", "staff_cost_price_string", "wholesale_price_string", "count_string", +func PercentFloatStringToUin32(s string) uint32 { + u := uint32(0) + if s != "" { + s = strings.ReplaceAll(s, "%", "") + } + f, err := strconv.ParseFloat(s, 64) + if err != nil { + //logger.Error("parse float err:", err) + return u + } + + u = uint32(f * 100) + return u +} + +func IntStringToUin32(s string) uint32 { + u := uint32(0) + if s != "" { + s = strings.ReplaceAll(s, "%", "") + } + i, err := strconv.Atoi(s) + if err != nil { + //logger.Error("parse float err:", err) + return u + } + + u = uint32(i) + return u } func NewStockImporter() *StockImporter { @@ -1555,3 +1352,16 @@ func NewStockImporter() *StockImporter { Inventories: make([]*ErpInventoryStock, 0), } } + +// UpdateStockCommodityRemark 更新库存商品备注信息 +func UpdateStockCommodityRemark(id int, remark string) error { + if remark == "" { + return nil + } + if err := orm.Eloquent.Model(&ErpStockCommodity{}).Where("id=?", id).Updates(map[string]interface{}{ + "remark": remark}).Error; err != nil { + return fmt.Errorf("[update err]:%v", err) + } + + return nil +} diff --git a/app/admin/models/file.go b/app/admin/models/file.go index 8c5953f..368ab31 100644 --- a/app/admin/models/file.go +++ b/app/admin/models/file.go @@ -156,6 +156,11 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i return nil, nil, errors.New("sheet list is empty") } + rowData, err := reader.GetRows(sheetList[0]) + if err != nil { + return nil, nil, fmt.Errorf("reader rows error: %v", err) + } + rows, err := reader.Rows(sheetList[0]) if err != nil { return nil, nil, fmt.Errorf("reader rows err: %v", err) @@ -170,6 +175,8 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i return nil, nil, errors.New("get cols is empty") } + sheetCols = checkExcelFormat(rowData, sheetCols) + var colsMap []map[string]interface{} if len(cols) == 0 { switch nType { // 导入类型:1 商品分类 2 商品资料 3 商品库存 @@ -204,7 +211,12 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i return nil, nil, errors.New("cols length does not match the number of columns") } + nCounter := len(rowData) //记录有数据的行数,空行则跳过循环 for rows.Next() { + if nCounter == 0 { + break + } + nCounter-- columns, err := rows.Columns() if err != nil { return nil, nil, fmt.Errorf("rows columns err: %v", err) @@ -232,6 +244,23 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i return mCols, colsMap, nil } +// checkExcelFormat校验excel表格格式,剔除最后1行的空格 +func checkExcelFormat(rowData, sheetCols [][]string) [][]string { + if findMaxLength(sheetCols) > len(rowData) { // 最后1行有空格,踢除 + newSheetCols := make([][]string, len(sheetCols)) + for i, col := range sheetCols { + if len(col) > len(rowData) { + newSheetCols[i] = col[:len(rowData)] + } else { + newSheetCols[i] = col + } + } + return newSheetCols + } + + return sheetCols +} + // 校验商品分类导入规则 // 导入商品分类校验报错: (1)只有3级,没有2级或1级 (2)有2,3级,但没有1级 func checkCategoryExcel(sheetCols [][]string) error { @@ -361,8 +390,9 @@ func checkStockExcel(sheetCols [][]string) error { } // 商品串码规则校验 当串码行数跟其他一致时正常遍历,如果小于其他行,则最后一行不遍历 todo + // 如何串码在商品库存表已经存在,则报错提示 if len(sheetCols[3]) <= nLow && i+1 < nLow { - if err := checkSerialCode(sheetCols[0][i], sheetCols[1][i], sheetCols[3][i]); err != nil { + if err := checkSerialCode(sheetCols[0][i], sheetCols[1][i], sheetCols[3][i], i); err != nil { return err } // 串码类商品数量只能为1 @@ -476,14 +506,15 @@ func isExistingSupplier(supplierName string) bool { return count > 0 } -func checkSerialCode(productName, productCode, serialCode string) error { +func checkSerialCode(productName, productCode, serialCode string, row int) error { var existingCommodity ErpCommodity + var existingStockCommodity ErpStockCommodity var queryCondition string - if productName != "" { + if productCode != "" { + queryCondition = "serial_number= ?" + } else if productName != "" { queryCondition = "name = ?" - } else if productCode != "" { - queryCondition = "serial_number = ?" } else { return errors.New("商品名称和商品编码不能都为空") } @@ -507,7 +538,16 @@ func checkSerialCode(productName, productCode, serialCode string) error { return errors.New("串码类商品,请填写正确的串码") } - return nil + result = orm.Eloquent.Where("imei = ?", serialCode).First(&existingStockCommodity) + if result.Error != nil { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { //没找到对应串码 + return nil + } + fmt.Println("Error:", result.Error) + return result.Error + } + + return errors.New("第" + strconv.Itoa(row+1) + "行串码重复,请勿重复导入") } func isNumericOrAlpha(s string) bool { @@ -725,7 +765,7 @@ func convertToErpCommodities(data []CommodityExcel) ([]ErpCommodity, error) { list, err := GetSupplier(GetSupplierRequest{Name: item.SupplierName}) if len(list) == 0 || errors.Is(err, gorm.ErrRecordNotFound) { - return nil, fmt.Errorf("有供应商未导入,请检查:[%v]", item.SupplierName) + return nil, fmt.Errorf("[%v]该供应商不存在,请新建供应商", item.SupplierName) } serialNumber := fmt.Sprintf("%s%04d", category.Number, @@ -749,7 +789,7 @@ func getCategoryByName(name string) (*Category, error) { err := orm.Eloquent.Debug().Model(&Category{}). Where("name = ?", name).First(&category).Error if errors.Is(err, gorm.ErrRecordNotFound) { - return nil, fmt.Errorf("有商品分类未导入,请检查:[%v]", name) + return nil, fmt.Errorf("[%v]该分类不存在,请先新建分类", name) } return &category, err } diff --git a/app/admin/models/user.go b/app/admin/models/user.go index f311282..ee5c578 100644 --- a/app/admin/models/user.go +++ b/app/admin/models/user.go @@ -86,7 +86,7 @@ const ( ) const DateTimeFormat = "2006-01-02" -const TimeFormat = "2006-01-02 15_04_05" +const TimeFormat = "2006-01-02 15-04-05" const ( ExportUrl = "https://dev.admin.deovo.com/load/export/" diff --git a/app/admin/router/inventory.go b/app/admin/router/inventory.go index 12ab4df..c61968b 100644 --- a/app/admin/router/inventory.go +++ b/app/admin/router/inventory.go @@ -9,9 +9,10 @@ import ( func registerInventoryManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { r := v1.Group("/inventory").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) - r.POST("list", inventorymanage.GetInventoryList) - r.POST("detail", inventorymanage.GetInventoryDetail) - r.POST("delivery", inventorymanage.DeliveryCargo) // 出库 - r.POST("print", inventorymanage.BatchPrint) // 批量打印 - r.POST("import", inventorymanage.BatchImport) + r.POST("list", inventorymanage.GetInventoryList) // 库存列表 + r.POST("detail", inventorymanage.GetInventoryDetail) // 库存详情 + r.POST("delivery", inventorymanage.DeliveryCargo) // 出库 + r.POST("print", inventorymanage.BatchPrint) // 批量打印 + r.POST("import", inventorymanage.BatchImport) // 库存导入 + r.POST("add_remark", inventorymanage.AddRemark) // 添加备注 } diff --git a/docs/docs.go b/docs/docs.go index 43b179f..ced15f0 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1462,7 +1462,40 @@ const docTemplate = `{ } } }, - "/api/v1/inventory/detail": { + "/api/v1/inventory/add_remark": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "添加备注", + "parameters": [ + { + "description": "添加备注模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/inventorymanage.AddRemarkReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/inventory/delivery": { "post": { "consumes": [ "application/json" @@ -1480,6 +1513,39 @@ const docTemplate = `{ "name": "request", "in": "body", "required": true, + "schema": { + "$ref": "#/definitions/inventorymanage.DeliveryCargoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/inventory/detail": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "查询库存详情", + "parameters": [ + { + "description": "查询库存详情模型", + "name": "request", + "in": "body", + "required": true, "schema": { "$ref": "#/definitions/models.ErpStockCommodityListReq" } @@ -1495,6 +1561,39 @@ const docTemplate = `{ } } }, + "/api/v1/inventory/import": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "库存导入", + "parameters": [ + { + "description": "上传excel文件", + "name": "file", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/inventory/list": { "post": { "consumes": [ @@ -1528,6 +1627,39 @@ const docTemplate = `{ } } }, + "/api/v1/inventory/print": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "批量打印", + "parameters": [ + { + "description": "批量打印模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.BatchPrintInfoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/loginlog": { "put": { "security": [ @@ -3482,10 +3614,10 @@ const docTemplate = `{ "basic.CommodityCreateRequest": { "type": "object", "required": [ - "brokerage_1", "erp_category_id", "erp_supplier_id", "imei_type", + "is_imei", "min_retail_price", "name", "retail_price", @@ -3510,7 +3642,11 @@ const docTemplate = `{ "type": "integer" }, "imei_type": { - "description": "1-无串码 2-串码(系统生成) 3-串码(手动添加)", + "description": "系统生成串码:2-是(系统生成) 3-否(手动添加)", + "type": "integer" + }, + "is_imei": { + "description": "是否串码:1-串码类 2-非串码", "type": "integer" }, "member_discount": { @@ -3863,6 +3999,75 @@ const docTemplate = `{ } } }, + "inventorymanage.AddRemarkReq": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "description": "商品库存列表id", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + } + } + }, + "inventorymanage.DeliveryCargoReq": { + "type": "object", + "required": [ + "id", + "state" + ], + "properties": { + "id": { + "description": "商品库存列表id", + "type": "integer" + }, + "state": { + "description": "库存状态:4-出库", + "type": "integer" + } + } + }, + "models.BatchPrintInfo": { + "type": "object", + "required": [ + "erp_commodity_name", + "imei", + "retail_price" + ], + "properties": { + "erp_commodity_name": { + "description": "商品名称", + "type": "string" + }, + "imei": { + "description": "商品串码", + "type": "string" + }, + "retail_price": { + "description": "指导零售价", + "type": "integer" + } + } + }, + "models.BatchPrintInfoReq": { + "type": "object", + "required": [ + "print_list_info" + ], + "properties": { + "print_list_info": { + "type": "array", + "items": { + "$ref": "#/definitions/models.BatchPrintInfo" + } + } + } + }, "models.CashierStore": { "type": "object", "properties": { @@ -4287,6 +4492,10 @@ const docTemplate = `{ "description": "1-无串码 2-串码(系统生成) 3-串码(手动添加)", "type": "integer" }, + "is_imei": { + "description": "是否串码:1-串码类 2-非串码", + "type": "integer" + }, "member_discount": { "description": "会员优惠", "type": "number" @@ -4535,6 +4744,10 @@ const docTemplate = `{ "description": "首次入库订单编号", "type": "string" }, + "remark": { + "description": "备注", + "type": "string" + }, "retail_price": { "description": "指导零售价", "type": "integer" @@ -5549,6 +5762,7 @@ const docTemplate = `{ "type": "string" }, "cooperative_business_id": { + "description": "合作商id", "type": "integer" }, "cooperative_name": { @@ -5613,6 +5827,7 @@ const docTemplate = `{ "type": "string" }, "status": { + "description": "状态", "type": "string" }, "store_id": { @@ -5620,7 +5835,7 @@ const docTemplate = `{ "type": "integer" }, "store_name": { - "description": "门店id", + "description": "门店名称", "type": "string" }, "updateBy": { @@ -5635,6 +5850,7 @@ const docTemplate = `{ "type": "integer" }, "username": { + "description": "用户名", "type": "string" } } diff --git a/docs/swagger.json b/docs/swagger.json index 6d31574..6c5d6e8 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -1451,7 +1451,40 @@ } } }, - "/api/v1/inventory/detail": { + "/api/v1/inventory/add_remark": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "添加备注", + "parameters": [ + { + "description": "添加备注模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/inventorymanage.AddRemarkReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/inventory/delivery": { "post": { "consumes": [ "application/json" @@ -1469,6 +1502,39 @@ "name": "request", "in": "body", "required": true, + "schema": { + "$ref": "#/definitions/inventorymanage.DeliveryCargoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, + "/api/v1/inventory/detail": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "查询库存详情", + "parameters": [ + { + "description": "查询库存详情模型", + "name": "request", + "in": "body", + "required": true, "schema": { "$ref": "#/definitions/models.ErpStockCommodityListReq" } @@ -1484,6 +1550,39 @@ } } }, + "/api/v1/inventory/import": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "库存导入", + "parameters": [ + { + "description": "上传excel文件", + "name": "file", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/inventory/list": { "post": { "consumes": [ @@ -1517,6 +1616,39 @@ } } }, + "/api/v1/inventory/print": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "库存管理" + ], + "summary": "批量打印", + "parameters": [ + { + "description": "批量打印模型", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.BatchPrintInfoReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/app.Response" + } + } + } + } + }, "/api/v1/loginlog": { "put": { "security": [ @@ -3471,10 +3603,10 @@ "basic.CommodityCreateRequest": { "type": "object", "required": [ - "brokerage_1", "erp_category_id", "erp_supplier_id", "imei_type", + "is_imei", "min_retail_price", "name", "retail_price", @@ -3499,7 +3631,11 @@ "type": "integer" }, "imei_type": { - "description": "1-无串码 2-串码(系统生成) 3-串码(手动添加)", + "description": "系统生成串码:2-是(系统生成) 3-否(手动添加)", + "type": "integer" + }, + "is_imei": { + "description": "是否串码:1-串码类 2-非串码", "type": "integer" }, "member_discount": { @@ -3852,6 +3988,75 @@ } } }, + "inventorymanage.AddRemarkReq": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "description": "商品库存列表id", + "type": "integer" + }, + "remark": { + "description": "备注", + "type": "string" + } + } + }, + "inventorymanage.DeliveryCargoReq": { + "type": "object", + "required": [ + "id", + "state" + ], + "properties": { + "id": { + "description": "商品库存列表id", + "type": "integer" + }, + "state": { + "description": "库存状态:4-出库", + "type": "integer" + } + } + }, + "models.BatchPrintInfo": { + "type": "object", + "required": [ + "erp_commodity_name", + "imei", + "retail_price" + ], + "properties": { + "erp_commodity_name": { + "description": "商品名称", + "type": "string" + }, + "imei": { + "description": "商品串码", + "type": "string" + }, + "retail_price": { + "description": "指导零售价", + "type": "integer" + } + } + }, + "models.BatchPrintInfoReq": { + "type": "object", + "required": [ + "print_list_info" + ], + "properties": { + "print_list_info": { + "type": "array", + "items": { + "$ref": "#/definitions/models.BatchPrintInfo" + } + } + } + }, "models.CashierStore": { "type": "object", "properties": { @@ -4276,6 +4481,10 @@ "description": "1-无串码 2-串码(系统生成) 3-串码(手动添加)", "type": "integer" }, + "is_imei": { + "description": "是否串码:1-串码类 2-非串码", + "type": "integer" + }, "member_discount": { "description": "会员优惠", "type": "number" @@ -4524,6 +4733,10 @@ "description": "首次入库订单编号", "type": "string" }, + "remark": { + "description": "备注", + "type": "string" + }, "retail_price": { "description": "指导零售价", "type": "integer" @@ -5538,6 +5751,7 @@ "type": "string" }, "cooperative_business_id": { + "description": "合作商id", "type": "integer" }, "cooperative_name": { @@ -5602,6 +5816,7 @@ "type": "string" }, "status": { + "description": "状态", "type": "string" }, "store_id": { @@ -5609,7 +5824,7 @@ "type": "integer" }, "store_name": { - "description": "门店id", + "description": "门店名称", "type": "string" }, "updateBy": { @@ -5624,6 +5839,7 @@ "type": "integer" }, "username": { + "description": "用户名", "type": "string" } } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 84b2e61..a333643 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -122,7 +122,10 @@ definitions: description: 主供应商 type: integer imei_type: - description: 1-无串码 2-串码(系统生成) 3-串码(手动添加) + description: 系统生成串码:2-是(系统生成) 3-否(手动添加) + type: integer + is_imei: + description: 是否串码:1-串码类 2-非串码 type: integer member_discount: description: 会员优惠 @@ -149,10 +152,10 @@ definitions: description: 指导采购价 type: integer required: - - brokerage_1 - erp_category_id - erp_supplier_id - imei_type + - is_imei - min_retail_price - name - retail_price @@ -394,6 +397,54 @@ definitions: - id - name type: object + inventorymanage.AddRemarkReq: + properties: + id: + description: 商品库存列表id + type: integer + remark: + description: 备注 + type: string + required: + - id + type: object + inventorymanage.DeliveryCargoReq: + properties: + id: + description: 商品库存列表id + type: integer + state: + description: 库存状态:4-出库 + type: integer + required: + - id + - state + type: object + models.BatchPrintInfo: + properties: + erp_commodity_name: + description: 商品名称 + type: string + imei: + description: 商品串码 + type: string + retail_price: + description: 指导零售价 + type: integer + required: + - erp_commodity_name + - imei + - retail_price + type: object + models.BatchPrintInfoReq: + properties: + print_list_info: + items: + $ref: '#/definitions/models.BatchPrintInfo' + type: array + required: + - print_list_info + type: object models.CashierStore: properties: store_id: @@ -702,6 +753,9 @@ definitions: imei_type: description: 1-无串码 2-串码(系统生成) 3-串码(手动添加) type: integer + is_imei: + description: 是否串码:1-串码类 2-非串码 + type: integer member_discount: description: 会员优惠 type: number @@ -884,6 +938,9 @@ definitions: original_sn: description: 首次入库订单编号 type: string + remark: + description: 备注 + type: string retail_price: description: 指导零售价 type: integer @@ -1613,6 +1670,7 @@ definitions: description: 头像 type: string cooperative_business_id: + description: 合作商id type: integer cooperative_name: description: 合作商名称 @@ -1660,12 +1718,13 @@ definitions: description: 性别 type: string status: + description: 状态 type: string store_id: description: 门店id type: integer store_name: - description: 门店id + description: 门店名称 type: string updateBy: type: string @@ -1676,6 +1735,7 @@ definitions: description: 编码 type: integer username: + description: 用户名 type: string type: object tools.Params: @@ -2769,12 +2829,54 @@ paths: summary: 字典类型列表数据 tags: - system/字典类型 - /api/v1/inventory/detail: + /api/v1/inventory/add_remark: + post: + consumes: + - application/json + parameters: + - description: 添加备注模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/inventorymanage.AddRemarkReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 添加备注 + tags: + - 库存管理 + /api/v1/inventory/delivery: post: consumes: - application/json parameters: - description: 出库模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/inventorymanage.DeliveryCargoReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 出库 + tags: + - 库存管理 + /api/v1/inventory/detail: + post: + consumes: + - application/json + parameters: + - description: 查询库存详情模型 in: body name: request required: true @@ -2787,7 +2889,28 @@ paths: description: OK schema: $ref: '#/definitions/models.ErpStockCommodityListResp' - summary: 出库 + summary: 查询库存详情 + tags: + - 库存管理 + /api/v1/inventory/import: + post: + consumes: + - application/json + parameters: + - description: 上传excel文件 + in: body + name: file + required: true + schema: + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 库存导入 tags: - 库存管理 /api/v1/inventory/list: @@ -2811,6 +2934,27 @@ paths: summary: 查询库存列表 tags: - 库存管理 + /api/v1/inventory/print: + post: + consumes: + - application/json + parameters: + - description: 批量打印模型 + in: body + name: request + required: true + schema: + $ref: '#/definitions/models.BatchPrintInfoReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/app.Response' + summary: 批量打印 + tags: + - 库存管理 /api/v1/loginlog: post: consumes: