新增库存导入接口

This commit is contained in:
chenlin 2023-11-23 20:38:11 +08:00
parent b95911437f
commit 147354b28c
21 changed files with 980 additions and 516 deletions

View File

@ -2,10 +2,12 @@ package inventorymanage
import ( import (
"errors" "errors"
"fmt"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"go-admin/app/admin/models" "go-admin/app/admin/models"
"go-admin/tools" "go-admin/tools"
"go-admin/tools/app" "go-admin/tools/app"
"io"
"net/http" "net/http"
) )
@ -131,3 +133,173 @@ func BatchPrint(c *gin.Context) {
app.OK(c, nil, "OK") app.OK(c, nil, "OK")
return return
} }
// BatchImport 库存导入
// @Summary 库存导入
// @Tags 库存管理
// @Produce json
// @Accept json
// @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()
file, header, err := c.Request.FormFile("file")
if err != nil {
//logger.Error("form file err:", err)
app.Error(c, http.StatusInternalServerError, err, "预览失败")
return
}
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)
_, 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("colsMap:", colsMap)
if len(colsMap) != 0 {
colsMap = colsMap[1:]
}
stockier := models.NewStockImporter()
err = stockier.ImportStockData2(colsMap)
if err != nil {
app.Error(c, http.StatusInternalServerError, err, err.Error())
return
}
app.OK(c, nil, "导入成功")
return
}

View File

@ -6,6 +6,7 @@ import (
"github.com/xuri/excelize/v2" "github.com/xuri/excelize/v2"
orm "go-admin/common/global" orm "go-admin/common/global"
"go-admin/logger" "go-admin/logger"
"go-admin/tools/config"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"gorm.io/gorm" "gorm.io/gorm"
"strconv" "strconv"
@ -14,9 +15,7 @@ import (
"time" "time"
) )
// ErpStock 库存表 // ErpStock 库存列表
//
//go:generate goqueryset -in commodity.go
type ErpStock struct { type ErpStock struct {
Model Model
@ -66,6 +65,7 @@ type ErpStockCommodity struct {
StockEndTime time.Time `json:"stock_end_time" gorm:"-"` // 最近入库结束时间 StockEndTime time.Time `json:"stock_end_time" gorm:"-"` // 最近入库结束时间
Age uint32 `json:"age" gorm:"-"` // 最近库龄 Age uint32 `json:"age" gorm:"-"` // 最近库龄
AllAge uint32 `json:"all_age" gorm:"-"` // 总库龄 AllAge uint32 `json:"all_age" gorm:"-"` // 总库龄
Remark string `json:"remark" gorm:"-"` // 备注
//Commodity ErpCommodity `json:"commodity" gorm:"-"` //Commodity ErpCommodity `json:"commodity" gorm:"-"`
} }
@ -95,7 +95,7 @@ type ErpCommodity struct {
ErpCategory *ErpCategory `json:"erp_category" gorm:"-"` ErpCategory *ErpCategory `json:"erp_category" gorm:"-"`
} }
// gen:qs // ErpCategory 商品分类
type ErpCategory struct { type ErpCategory struct {
Model Model
@ -111,7 +111,7 @@ type ErpCategory struct {
// erp_category // erp_category
} }
// gen:qs // ErpSupplier 供应商
type ErpSupplier struct { type ErpSupplier struct {
Model Model
@ -131,7 +131,6 @@ type ErpSupplier struct {
// erp_supplier // erp_supplier
} }
// gen:qs
type ErpInventoryStock struct { type ErpInventoryStock struct {
Model Model
@ -156,7 +155,6 @@ type ErpInventoryStock struct {
// erp_inventory_stock // erp_inventory_stock
} }
// gen:qs
type ErpInventoryStockCommodity struct { type ErpInventoryStockCommodity struct {
Model Model
@ -183,6 +181,7 @@ type ErpInventoryStockCommodity struct {
// erp_inventory_stock_commodity // erp_inventory_stock_commodity
} }
// IdInit 新增/编辑商品时获取分类和供应商信息
func (c *ErpCommodity) IdInit() { func (c *ErpCommodity) IdInit() {
if c.ErpCategoryId != 0 { if c.ErpCategoryId != 0 {
if c.ErpCategory == nil { if c.ErpCategory == nil {
@ -206,6 +205,7 @@ func (c *ErpCommodity) IdInit() {
} }
} }
// GetErpCategory 根据id查询分类信息
func GetErpCategory(id uint32) (*ErpCategory, error) { func GetErpCategory(id uint32) (*ErpCategory, error) {
category := new(ErpCategory) category := new(ErpCategory)
err := orm.Eloquent.Table("erp_category").Where("id=?", id).Find(category).Error err := orm.Eloquent.Table("erp_category").Where("id=?", id).Find(category).Error
@ -216,6 +216,7 @@ func GetErpCategory(id uint32) (*ErpCategory, error) {
return category, nil return category, nil
} }
// GetErpSupplier 根据id查询供应商
func GetErpSupplier(id uint32) (*ErpSupplier, error) { func GetErpSupplier(id uint32) (*ErpSupplier, error) {
supplier := new(ErpSupplier) supplier := new(ErpSupplier)
err := orm.Eloquent.Table("erp_supplier").Where("id=?", id).Find(supplier).Error err := orm.Eloquent.Table("erp_supplier").Where("id=?", id).Find(supplier).Error
@ -226,6 +227,7 @@ func GetErpSupplier(id uint32) (*ErpSupplier, error) {
return supplier, err return supplier, err
} }
// SetErpCategory 新增/编辑商品时设置分类信息
func (c *ErpCommodity) SetErpCategory() error { func (c *ErpCommodity) SetErpCategory() error {
if c.ErpCategoryId != 0 { if c.ErpCategoryId != 0 {
category, err := GetErpCategory(c.ErpCategoryId) category, err := GetErpCategory(c.ErpCategoryId)
@ -537,99 +539,6 @@ func (m *CommodityNumberCount) GetErpCommodityNumberByCategoryId(categoryId uint
return commodity.Number + 1, nil return commodity.Number + 1, nil
} }
func GetErpCategorySubMap() (map[string]*ErpCategorySub, error) {
var erpCategories []ErpCategory
err := orm.Eloquent.Table("erp_category").Find(&erpCategories).Error
if err != nil {
//logger.Error("erp categories err:", err)
return nil, err
}
categoriesMaps := make(map[string]*ErpCategorySub, 0)
pidMap := make(map[uint32]string, 0)
for i, _ := range erpCategories {
if erpCategories[i].Level == 1 {
if erpCategories[i].Pid != 0 {
logger.Error("erp categories level 1 pid gt 0")
return nil, errors.New("erp categories level 1 pid gt 0")
}
if _, ok := categoriesMaps[erpCategories[i].Name]; !ok {
categoriesMaps[erpCategories[i].Name] = &ErpCategorySub{
Id: erpCategories[i].ID,
Name: erpCategories[i].Name,
FullNum: erpCategories[i].FullNum,
SubMap: make(map[string]ErpCategory, 0),
}
pidMap[erpCategories[i].ID] = erpCategories[i].Name
}
}
}
for i, _ := range erpCategories {
if erpCategories[i].Level == 2 {
if erpCategories[i].Pid == 0 {
logger.Error("erp categories level 2 pid is 0")
return nil, errors.New("erp categories level 2 pid is 0")
}
name, ok := pidMap[erpCategories[i].Pid]
if ok {
categoriesMaps[name].SubMap[erpCategories[i].Name] = erpCategories[i]
}
}
}
return categoriesMaps, nil
}
func ErpCategoryCreate(name string, pid uint32) (*ErpCategory, error) {
category := &ErpCategory{
Number: 0,
State: 2,
Level: 1,
Pid: pid,
}
var (
pCategory ErpCategory
sCategory ErpCategory
)
qs := orm.Eloquent.Table("erp_category")
if category.Pid != 0 {
category.Level = 2
qs = qs.Where("id=?", pid)
err := orm.Eloquent.Table("erp_category").Where("pid=?", pid).Order("id DESC").Limit(1).Find(&sCategory).Error
if err != nil {
//logger.Error("s category err:", err)
return category, err
}
} else {
qs = qs.Where("level=1")
}
err := qs.Order("id DESC").Limit(1).Find(&pCategory).Error
if err != nil && err != RecordNotFound {
//logger.Error("cat erp commodity err:", err)
return category, err
}
if category.Level == 1 {
category.Number = pCategory.Number + 1
category.FullNum = pCategory.FullNum + 1000
category.Name = fmt.Sprintf("%03d%s", category.Number, name)
} else {
category.Number = sCategory.Number + 1
category.Name = fmt.Sprintf("%03d-%03d%s", pCategory.Number, category.Number, name)
category.FullNum = pCategory.FullNum + category.Number
}
err = orm.Eloquent.Create(category).Error
if err != nil {
//logger.Error("create commodity err:", err)
return category, err
}
return category, nil
}
type ErpSupplierListResp struct { type ErpSupplierListResp struct {
List []ErpSupplier `json:"list"` List []ErpSupplier `json:"list"`
Total int `json:"total"` Total int `json:"total"`
@ -638,11 +547,6 @@ type ErpSupplierListResp struct {
ExportUrl string `json:"export_url"` ExportUrl string `json:"export_url"`
} }
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",
}
var EsfLock sync.Mutex var EsfLock sync.Mutex
var EsStockLock sync.Mutex var EsStockLock sync.Mutex
@ -659,9 +563,9 @@ type ErpStockFileExcel struct {
RetailPriceString string `json:"retail_price_string"` RetailPriceString string `json:"retail_price_string"`
MinRetailPriceString string `json:"min_retail_price_string"` MinRetailPriceString string `json:"min_retail_price_string"`
StaffCostPriceString string `json:"staff_cost_price_string"` StaffCostPriceString string `json:"staff_cost_price_string"` // 员工成本价加价
WholesalePriceString string `json:"wholesale_price_string"` WholesalePriceString string `json:"wholesale_price_string"` // 指导采购价
CountString string `json:"count_string"` CountString string `json:"count_string"` // 数量
//StoreName string `json:"store_name"` //StoreName string `json:"store_name"`
//ErpCommodityName string `json:"erp_commodity_name"` //ErpCommodityName string `json:"erp_commodity_name"`
@ -674,15 +578,6 @@ type ErpStockFileExcel struct {
ErpStockCommodity ErpStockCommodity
} }
func NewStockImporter() *StockImporter {
return &StockImporter{
CensusMap: make(map[uint32]map[uint32]uint32, 0),
CommodityMap: make(map[uint32]*ErpCommodity),
StoreMap: make(map[uint32]string, 0),
Inventories: make([]*ErpInventoryStock, 0),
}
}
func (e *ErpStockFileExcel) Processing() { func (e *ErpStockFileExcel) Processing() {
e.Count = IntStringToUin32(e.CountString) e.Count = IntStringToUin32(e.CountString)
if e.IsIMEI == "是" { if e.IsIMEI == "是" {
@ -709,51 +604,41 @@ func (e *ErpStockFileExcel) Processing() {
} }
func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel) error { func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error {
//allCategoriesMap, err := GetErpCategorySubMap() list, err := transStockData(colsMap)
//if err != nil { if err != nil {
// logger.Error("all categories map err:", err) return err
// return }
//}
// 加锁 var erpStockCommodity []ErpStockCommodity
//m.CensusMap = make(map[uint32]map[uint32]uint32, 0)
storeNameMap := make(map[string]uint32, 0) storeNameMap := make(map[string]uint32, 0)
erpCommodityMap := make(map[string]*ErpCommodity, 0) erpCommodityMap := make(map[string]*ErpCommodity, 0)
erpCategoryNameMap := make(map[string]uint32, 0)
erpSupplierNameMap := make(map[string]uint32, 0) erpSupplierNameMap := make(map[string]uint32, 0)
storeNames := make([]string, 0, len(list)) storeNames := make([]string, 0, len(list))
erpCommodityNames := make([]string, 0, len(list)) erpCommodityNames := make([]string, 0, len(list))
erpCategoryNames := make([]string, 0, len(list))
erpSupplierNames := make([]string, 0, len(list)) erpSupplierNames := make([]string, 0, len(list))
for i, _ := range list { for i, _ := range list {
list[i].Processing()
_, ok1 := storeNameMap[list[i].StoreName] _, ok1 := storeNameMap[list[i].StoreName]
if !ok1 { if !ok1 {
storeNames = append(storeNames, list[i].StoreName) storeNames = append(storeNames, list[i].StoreName)
} }
_, ok2 := erpCommodityMap[list[i].ErpCommodityName] _, ok2 := erpCommodityMap[list[i].Name]
if !ok2 { if !ok2 {
erpCommodityNames = append(erpCommodityNames, list[i].ErpCommodityName) erpCommodityNames = append(erpCommodityNames, list[i].Name)
} }
_, ok3 := erpCategoryNameMap[list[i].ErpCategoryName] _, ok3 := erpSupplierNameMap[list[i].SupplierName]
if !ok3 { if !ok3 {
erpCategoryNames = append(erpCategoryNames, list[i].ErpCategoryName) erpSupplierNames = append(erpSupplierNames, list[i].SupplierName)
}
_, ok4 := erpSupplierNameMap[list[i].ErpSupplierName]
if !ok4 {
erpSupplierNames = append(erpSupplierNames, list[i].ErpSupplierName)
} }
storeNameMap[list[i].StoreName] = uint32(0) storeNameMap[list[i].StoreName] = uint32(0)
erpCommodityMap[list[i].ErpCommodityName] = nil erpCommodityMap[list[i].Name] = nil
erpCategoryNameMap[list[i].ErpCategoryName] = uint32(0) erpSupplierNameMap[list[i].SupplierName] = uint32(0)
erpSupplierNameMap[list[i].ErpSupplierName] = uint32(0)
} }
var stores []Store var stores []Store
err := orm.Eloquent.Table("store").Where("name IN (?)", storeNames).Find(&stores).Error err = orm.Eloquent.Table("store").Where("name IN (?)", storeNames).Find(&stores).Error
if err != nil { if err != nil {
//logger.Error("stores err:", err) //logger.Error("stores err:", err)
return err return err
@ -766,16 +651,9 @@ func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel
return err return err
} }
var erpCategories []ErpCategory
err = orm.Eloquent.Table("erp_category").Where("name IN (?)", erpCategoryNames).Find(&erpCategories).Error
if err != nil {
//logger.Error("stores err:", err)
return err
}
var erpSuppliers []ErpSupplier var erpSuppliers []ErpSupplier
err = orm.Eloquent.Table("erp_supplier").Debug().Where("name IN (?)", erpSupplierNames).Find(&erpSuppliers).Error err = orm.Eloquent.Table("erp_supplier").Debug().Where("name IN (?)", erpSupplierNames).Find(&erpSuppliers).Error
if err != nil && err != RecordNotFound { if err != nil && !errors.Is(err, RecordNotFound) {
//logger.Error("stores err:", err) //logger.Error("stores err:", err)
return err return err
} }
@ -790,76 +668,287 @@ func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel
m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i] m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i]
} }
for i, _ := range erpCategories { for i, _ := range erpSuppliers {
erpCategoryNameMap[erpCategories[i].Name] = erpCategories[i].ID 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")
return errors.New("erp supplier name err")
}
// 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价
nStaffCostPrice, err := strconv.ParseUint(list[i].StaffCostPrice, 10, 32)
if err != nil {
return fmt.Errorf("员工成本价转换有误:[%v]", err)
}
nWholesalePrice, err := strconv.ParseUint(list[i].WholesalePrice, 10, 32) // 指导采购价
if err != nil {
return fmt.Errorf("指导采购价转换有误:[%v]", err)
}
if nStaffCostPrice < nWholesalePrice {
return fmt.Errorf("导入价格有误,员工成本价低于指导采购价")
}
nCount, err := strconv.ParseUint(list[i].Count, 10, 32)
if err != nil {
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,
}
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}
}
}
if err = m.processErpStocks(erpStockCommodity); err != nil {
return err
}
return nil
}
func (m *StockImporter) processErpStocks(erpStocks []ErpStockCommodity) error {
begin := orm.Eloquent.Begin()
total := len(erpStocks)
size := 200
page := (total + size - 1) / size
errGroup := errgroup.Group{}
for i := 0; i < page; i++ {
start := i * size
end := (i + 1) * size
if end > total {
end = total
}
stockList := erpStocks[start:end]
errGroup.Go(func() error {
return createStockList(begin, stockList)
})
}
err := m.ErpStockCountUpdate(begin)
if err != nil {
begin.Rollback()
return err
}
err = errGroup.Wait()
if err != nil {
begin.Rollback()
return err
}
err = begin.Commit().Error
if err != nil {
begin.Rollback()
return err
}
return nil
}
func createStockList(begin *gorm.DB, stockList []ErpStockCommodity) error {
err := begin.Create(&stockList).Error
if err != nil {
begin.Rollback()
return err
}
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 { for i, _ := range erpSuppliers {
erpSupplierNameMap[erpSuppliers[i].Name] = erpSuppliers[i].ID erpSupplierNameMap[erpSuppliers[i].Name] = erpSuppliers[i].ID
} }
//categoryCommodityNumMap := make(map[uint32]uint32, 0)
//for i, _ := range erpCommodities {
// var commodity ErpCommodity
// err = orm.Eloquent.Table("erp_commodity").Where("erp_category_id=?", erpCommodities[i].ErpCategoryId).
// Order("id DESC").Limit(1).Find(&commodity).Error
// if err != nil {
// logger.Error("commodity err:", err)
// }
// categoryCommodityNumMap[erpCommodities[i].ErpCategoryId] = commodity.Number
//}
nowTime := time.Now() nowTime := time.Now()
//erpStockCommodity := make([]ErpStockCommodity, 0, len(list))
for i, _ := range list { for i, _ := range list {
v1, ok1 := storeNameMap[list[i].StoreName] v1, ok1 := storeNameMap[list[i].StoreName]
v2, ok2 := erpCommodityMap[list[i].ErpCommodityName]
v3, ok3 := erpCategoryNameMap[list[i].ErpCategoryName]
v4, ok4 := erpSupplierNameMap[list[i].ErpSupplierName]
if !ok1 { if !ok1 {
logger.Error("store name err") logger.Error("store name err")
return errors.New("store name err") return nil, errors.New("store name err")
} }
if !ok2 && v2 == nil {
v2, ok2 := erpCommodityMap[list[i].Name]
if !ok2 || v2 == nil {
logger.Error("erp commodity name err") logger.Error("erp commodity name err")
return errors.New("erp commodity name err") return nil, errors.New("erp commodity name err")
} }
v3, ok3 := erpSupplierNameMap[list[i].SupplierName]
if !ok3 { if !ok3 {
logger.Error("erp category name err")
return errors.New("erp category name err")
}
if !ok4 {
logger.Error("erp supplier name err") logger.Error("erp supplier name err")
return errors.New("erp supplier name err") return nil, errors.New("erp supplier name err")
} }
list[i].StoreId = v1 // 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价
list[i].ErpCommodityId = v2.ID nStaffCostPrice, err := strconv.ParseUint(list[i].StaffCostPrice, 10, 32)
list[i].CommoditySerialNumber = v2.SerialNumber if err != nil {
list[i].ErpCategoryId = v3 return nil, fmt.Errorf("员工成本价转换有误:[%v]", err)
list[i].ErpSupplierId = v4 }
list[i].State = 1 nWholesalePrice, err := strconv.ParseUint(list[i].WholesalePrice, 10, 32) // 指导采购价
list[i].StorageType = 1 if err != nil {
list[i].FirstStockTime = nowTime return nil, fmt.Errorf("指导采购价转换有误:[%v]", err)
}
if nStaffCostPrice < nWholesalePrice {
return nil, fmt.Errorf("导入价格有误,员工成本价低于指导采购价")
}
//v6, ok6 := m.CommodityMap[v2] nCount, err := strconv.ParseUint(list[i].Count, 10, 32)
if err != nil {
return nil, fmt.Errorf("数量转换有误:[%v]", err)
}
_, ok5 := m.CensusMap[list[i].StoreId] stockCommodity := ErpStockCommodity{
if ok5 { StoreId: v1,
m.CensusMap[list[i].StoreId][list[i].ErpCommodityId] += list[i].Count 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 { } else {
m.CensusMap[list[i].StoreId] = map[uint32]uint32{list[i].ErpCommodityId: list[i].Count} m.CensusMap[stockCommodity.StoreId] = map[uint32]uint32{stockCommodity.ErpCommodityId: stockCommodity.Count}
} }
//v5, ok5 := categoryCommodityNumMap[list[i].ErpCategoryId]
//if !ok5 {
// logger.Error("category commodity num err")
// return errors.New("category commodity num err")
//}
} }
return nil return erpStockCommodity, nil
} }
func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error { func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error {
@ -929,7 +1018,7 @@ func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error {
return nil return nil
} }
func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockFileExcel) error { func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockCommodity) error {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
//logger.Error("err:", err) //logger.Error("err:", err)
@ -991,53 +1080,10 @@ func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockFil
return err return err
} }
//go func() {
// //inventoryStockIdMap := make(map[string]uint32, 0)
// //for _, inventorymanage := range m.Inventories {
// // //err := gdb.Create(inventorymanage).Error
// // err := orm.Eloquent.Create(inventorymanage).Error
// // if err != nil {
// // logger.Error("create erp inventorymanage stock err:", err)
// // return
// // }
// // inventoryStockIdMap[fmt.Sprintf("%d_%d", inventorymanage.StoreId, inventorymanage.ErpCommodityId)] = inventorymanage.ID
// //}
//
// //stock := ErpStockFileExcel{}
// //ErpInventoryStock
// for i, _ := range list {
// v, ok := inventoryStockIdMap[fmt.Sprintf("%d_%d", list[i].StoreId, list[i].ErpCommodityId)]
// if ok {
// inventoryCommodity := &ErpInventoryStockCommodity{
// ErpInventoryStockId: v,
// ErpCommodityId: list[i].ErpCommodityId,
// ErpCommodityName: list[i].ErpCommodityName,
// SerialNumber: list[i].SerialNumber,
// IMEIType: list[i].IMEIType,
// IMEI: list[i].IMEI,
// ErpSupplierId: list[i].ErpSupplierId,
// ErpSupplierName: list[i].ErpSupplierName,
// StockTime: list[i].StockTime,
// RetailPrice: list[i].RetailPrice,
// MinRetailPrice: list[i].MinRetailPrice,
// StaffCostPrice: list[i].StaffCostPrice,
// WholesalePrice: list[i].WholesalePrice,
// Count: list[i].Count,
// }
// //err := gdb.Create(inventoryCommodity).Error
// err := orm.Eloquent.Create(inventoryCommodity).Error
// if err != nil {
// logger.Error("create erp inventorymanage stock commodity err:", err)
// return
// }
// }
//
// }
//}()
return nil return nil
} }
func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []ErpStockFileExcel) []*ErpInventoryStockCommodity { func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []ErpStockCommodity) []*ErpInventoryStockCommodity {
inventoryList := make([]*ErpInventoryStockCommodity, 0, len(list)) inventoryList := make([]*ErpInventoryStockCommodity, 0, len(list))
for i, _ := range list { for i, _ := range list {
v, ok := inventoryStockIdMap[fmt.Sprintf("%d_%d", list[i].StoreId, list[i].ErpCommodityId)] v, ok := inventoryStockIdMap[fmt.Sprintf("%d_%d", list[i].StoreId, list[i].ErpCommodityId)]
@ -1070,6 +1116,7 @@ func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []
return inventoryList return inventoryList
} }
// ErpCommodityListExport 导出商品列表
func ErpCommodityListExport(list []ErpCommodity) (string, error) { func ErpCommodityListExport(list []ErpCommodity) (string, error) {
file := excelize.NewFile() file := excelize.NewFile()
streamWriter, err := file.NewStreamWriter("Sheet1") streamWriter, err := file.NewStreamWriter("Sheet1")
@ -1113,6 +1160,82 @@ func ErpCommodityListExport(list []ErpCommodity) (string, error) {
return url + fileName, nil return url + fileName, nil
} }
// InventoryDetailListExport 导出库存商品列表
func InventoryDetailListExport(list []ErpStockCommodity) (string, error) {
file := excelize.NewFile()
streamWriter, err := file.NewStreamWriter("Sheet1")
if err != nil {
fmt.Println(err)
}
url := config.ExportConfig.Url
fileName := time.Now().Format(TimeFormat) + "商品" + ".xlsx"
fmt.Println("url fileName:", url+fileName)
title := []interface{}{"商品编号", "商品名称", "商品分类", "是否串码", "商品串码", "所属门店", "供应商", "首次入库时间", "首次入库方式",
"首次入库订单编号", "最近入库时间", "入库采购价", "入库员工成本价", "最近库龄", "总库龄", "当前状态", "备注"}
cell, _ := excelize.CoordinatesToCellName(1, 1)
if err = streamWriter.SetRow(cell, title); err != nil {
fmt.Println(err)
}
var row []interface{}
for rowId := 0; rowId < len(list); rowId++ {
isIMEIType := "是"
if list[rowId].IMEIType == 1 {
isIMEIType = "否"
}
storageType := "系统入库"
if list[rowId].StorageType == 2 {
storageType = "采购入库"
}
state := "库存中"
switch list[rowId].State {
case 1:
state = "库存中"
case 2:
state = "已售"
case 3:
state = "采购退货"
case 4:
state = "调拨中"
}
row = []interface{}{
list[rowId].CommoditySerialNumber,
list[rowId].ErpCommodityName,
list[rowId].ErpCategoryName,
isIMEIType,
list[rowId].IMEI,
list[rowId].StoreName,
list[rowId].ErpSupplierName,
list[rowId].FirstStockTime,
storageType,
list[rowId].StockSn,
list[rowId].StockTime,
list[rowId].WholesalePrice,
list[rowId].StaffCostPrice,
list[rowId].Age,
list[rowId].AllAge,
state,
list[rowId].Remark}
cell, _ := excelize.CoordinatesToCellName(1, rowId+2)
if err := streamWriter.SetRow(cell, row); err != nil {
fmt.Println(err)
}
}
if err := streamWriter.Flush(); err != nil {
fmt.Println(err)
}
fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
fmt.Println(err)
}
return url + fileName, nil
}
// ErpCategoryListExport 导出商品分类
func ErpCategoryListExport(list []ErpCategory) (string, error) { func ErpCategoryListExport(list []ErpCategory) (string, error) {
file := excelize.NewFile() file := excelize.NewFile()
streamWriter, err := file.NewStreamWriter("Sheet1") streamWriter, err := file.NewStreamWriter("Sheet1")
@ -1166,6 +1289,7 @@ type ErpStockListReq struct {
PageSize int `json:"page_size"` // 页码 PageSize int `json:"page_size"` // 页码
//IsExport uint32 `json:"is_export"` // 1-导出 //IsExport uint32 `json:"is_export"` // 1-导出
} }
type ErpStockListResp struct { type ErpStockListResp struct {
List []ErpStock `json:"list"` List []ErpStock `json:"list"`
Total int `json:"total"` Total int `json:"total"`
@ -1232,14 +1356,6 @@ func ErpStockCommodityListSetAge(commodities []ErpStockCommodity) {
} }
} }
func ErpStockCommodityListSetCommodity(commodities []ErpStockCommodity) {
nowTime := time.Now()
for i, _ := range commodities {
commodities[i].Age = uint32(nowTime.Sub(commodities[i].StockTime).Hours()) / 24
commodities[i].AllAge = uint32(nowTime.Sub(commodities[i].FirstStockTime).Hours()) / 24
}
}
// ErpStockCommodityListReq 库存详情接口请求参数 // ErpStockCommodityListReq 库存详情接口请求参数
type ErpStockCommodityListReq struct { type ErpStockCommodityListReq struct {
ErpStockId uint32 `json:"erp_stock_id"` // 库存id ErpStockId uint32 `json:"erp_stock_id"` // 库存id
@ -1303,11 +1419,11 @@ func (m *ErpStockCommodityListReq) GetDetailList() (*ErpStockCommodityListResp,
return resp, err return resp, err
} }
//listExport, err := ErpCommodityListExport(commodities) listExport, err := InventoryDetailListExport(commodities)
//if err != nil { if err != nil {
// logger.Error("list export err:", err) //logger.Error("list export err:", err)
//} }
//resp.ExportUrl = listExport resp.ExportUrl = listExport
} else { } else {
err := qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error err := qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error
if err != nil && !errors.Is(err, RecordNotFound) { if err != nil && !errors.Is(err, RecordNotFound) {
@ -1424,3 +1540,18 @@ func StringToFloat(req string) (float64, error) {
return strconv.ParseFloat(req, 64) 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 NewStockImporter() *StockImporter {
return &StockImporter{
CensusMap: make(map[uint32]map[uint32]uint32, 0),
CommodityMap: make(map[uint32]*ErpCommodity),
StoreMap: make(map[uint32]string, 0),
Inventories: make([]*ErpInventoryStock, 0),
}
}

View File

@ -13,6 +13,8 @@ import (
"reflect" "reflect"
"strconv" "strconv"
"strings" "strings"
"time"
"unicode"
) )
type CategoryExcel struct { type CategoryExcel struct {
@ -38,6 +40,18 @@ type CommodityExcel struct {
Remark string `json:"remark"` // 备注 Remark string `json:"remark"` // 备注
} }
type StockExcel struct {
Name string `json:"name"` // 商品名称
SerialNum string `json:"serial_num"` // 商品编号
StoreName string `json:"store_name" binding:"required"` // 所属门店
SysGenerate string `json:"sys_generate"` // 系统生成串码
WholesalePrice string `json:"wholesale_price" binding:"required"` // 指导采购价
StaffCostPrice string `json:"staff_cost_price" binding:"required"` // 员工成本价=员工成本价加价+指导采购价
SupplierName string `json:"supplier_name" binding:"required"` // 供应商名称
StockTime string `json:"stock_time"` // 入库时间
Count string `json:"count" binding:"required"` // 数量
}
// 获取struct的tag标签匹配excel导入数据 // 获取struct的tag标签匹配excel导入数据
func getJSONTagNames(s interface{}) []string { func getJSONTagNames(s interface{}) []string {
valueType := reflect.TypeOf(s) valueType := reflect.TypeOf(s)
@ -90,6 +104,8 @@ func FileExcelReader(d []byte, cols []string) ([]byte, []map[string]interface{},
cols = getJSONTagNames(CategoryExcel{}) cols = getJSONTagNames(CategoryExcel{})
case "导商品": case "导商品":
cols = getJSONTagNames(CommodityExcel{}) cols = getJSONTagNames(CommodityExcel{})
case "导库存":
cols = getJSONTagNames(StockExcel{})
default: default:
cols = make([]string, len(sheetCols)) cols = make([]string, len(sheetCols))
for i := range sheetCols { for i := range sheetCols {
@ -156,7 +172,7 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i
var colsMap []map[string]interface{} var colsMap []map[string]interface{}
if len(cols) == 0 { if len(cols) == 0 {
switch nType { // 导入类型1 商品分类 2 商品资料 switch nType { // 导入类型1 商品分类 2 商品资料 3 商品库存
case 1: case 1:
if sheetList[0] != "导分类" { if sheetList[0] != "导分类" {
return nil, nil, errors.New("格式错误不是分类模版excel") return nil, nil, errors.New("格式错误不是分类模版excel")
@ -173,6 +189,14 @@ func FileExcelImport(d []byte, cols []string, nType int) ([]byte, []map[string]i
return nil, nil, err return nil, nil, err
} }
cols = getJSONTagNames(CommodityExcel{}) cols = getJSONTagNames(CommodityExcel{})
case 3:
if sheetList[0] != "导库存" {
return nil, nil, errors.New("格式错误不是库存模版excel")
}
if err := checkStockExcel(sheetCols); err != nil {
return nil, nil, err
}
cols = getJSONTagNames(StockExcel{})
default: default:
return nil, nil, errors.New("格式错误不是商品分类或资料模版excel") return nil, nil, errors.New("格式错误不是商品分类或资料模版excel")
} }
@ -273,6 +297,228 @@ func checkCommodityExcel(sheetCols [][]string) error {
return nil return nil
} }
// 校验库存导入规则
// 导入规则:
// (1)商品名称100 字符内,商品名称和商品编号可只填一项,同时填写时优先按照商品名称导库存;
// 且需为已有商品名称,否则红框展示,下方红字提示“该商品不存在,请新建商品”
// (2)商品编号:限纯数字,商品名称和商品编号可只填一项,同时填写时优先按照商品名称导库存;
// 且需为已有商品编号,否则红框展示,下方红字提示“该商品编号不存在”
// (3)所属门店必填项100 字符内;且需为已有门店,否则红框展示,下方红字提示“该门店不存在,请新建门店”
// (4)商品串码100 字符内,限制仅可填数字或英文;串码类必填,非串码不填
// 如果是串码类商品没填串码或者填了中文,红框展示,下方红字提示“串码类商品,请填写正确地串码”
// 如果是非串码商品,填了串码,红框展示,下方红字提示“非串码商品,无需填写串码”
// (5)采购价必填项入库时的采购价0 数字
// (6)员工成本价必填项入库时的员工成本价0 数字
// (7)供应商必填项100 字符内,且需为已有供应商,否则红框展示,下方红字提示“该供应商不存在,请新建供应商”
// (8)入库时间非必填项含年月日填写后入库时间会按照填写的日期0点展示不填写则按照实际导入成功时间展示
// (9)数量必填项限制≥1正整数
// 串码类商品需拆分成每个数量为1单独导入
// 非串码可大于1直接导入 * 串码类商品如数量填写1红框展示下方红字提示“串码类商品数量只能为1”
func checkStockExcel(sheetCols [][]string) error {
if len(sheetCols) != 9 {
return errors.New("模版错误,请检查文件")
}
maxLength := findMaxLength(sheetCols)
nLow, nMax := determineLowAndMax(sheetCols)
if nMax < maxLength {
return errors.New("第" + strconv.Itoa(nMax+1) + "行商品名称和商品编号不能同时为空")
}
//先遍历第1列
for i := 1; i < nLow; i++ {
if sheetCols[0][i] == "" && sheetCols[1][i] == "" { // 商品名称和编号不能都为空
return errors.New("第" + strconv.Itoa(i+1) + "行商品名称和商品编号不能同时为空")
}
}
for i := 1; i < nLow; i++ { // todo
if !isExistingProduct(sheetCols[0][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品不存在,请新建商品")
}
// 商品编号必须为纯数字
if sheetCols[1][i] != "" {
if _, err := strconv.Atoi(sheetCols[1][i]); err != nil {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号必须为纯数字")
}
}
if !isExistingProductCode(sheetCols[1][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行商品编号不存在")
}
// 所属门店不能为空
if sheetCols[2][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行所属门店不能为空")
}
if !isExistingStore(sheetCols[2][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行门店不存在,请新建门店")
}
// 商品串码规则校验 当串码行数跟其他一致时正常遍历,如果小于其他行,则最后一行不遍历 todo
if len(sheetCols[3]) <= nLow && i+1 < nLow {
if err := checkSerialCode(sheetCols[0][i], sheetCols[1][i], sheetCols[3][i]); err != nil {
return err
}
// 串码类商品数量只能为1
if sheetCols[3][i] != "" && sheetCols[8][i] != "1" {
return errors.New("第" + strconv.Itoa(i+1) + "行串码类商品数量只能为1")
}
}
// 采购价、员工成本价必须大于0
if purchasePrice, err := strconv.Atoi(sheetCols[4][i]); err != nil || purchasePrice <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行采购价必须是大于0的数字")
}
if employeeCost, err := strconv.Atoi(sheetCols[5][i]); err != nil || employeeCost <= 0 {
return errors.New("第" + strconv.Itoa(i+1) + "行员工成本价必须是大于0的数字")
}
// 供应商不能为空
if sheetCols[6][i] == "" {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不能为空")
}
if !isExistingSupplier(sheetCols[6][i]) {
return errors.New("第" + strconv.Itoa(i+1) + "行供应商不存在,请新建供应商")
}
// 入库时间格式校验
if len(sheetCols[7]) < nLow && i+1 < nLow {
if sheetCols[7][i] != "" {
parsedTime, err := time.Parse("2006/1/2", sheetCols[7][i])
if err != nil {
return errors.New("第" + strconv.Itoa(i+1) + "行入库时间格式错误应为YYYY-MM-DD")
}
// 格式化时间为指定格式
formattedTime := parsedTime.Format(DateTimeFormat)
sheetCols[7][i] = formattedTime + "00-00-00"
}
}
// 数量必须为正整数
if quantity, err := strconv.Atoi(sheetCols[8][i]); err != nil || quantity < 1 {
return errors.New("第" + strconv.Itoa(i+1) + "行数量必须是大于等于1的整数")
}
}
return nil
}
func findMaxLength(sheetCols [][]string) int {
maxLength := 0
for _, col := range sheetCols {
if len(col) > maxLength {
maxLength = len(col)
}
}
return maxLength
}
func determineLowAndMax(sheetCols [][]string) (int, int) {
nLow := len(sheetCols[0])
nMax := len(sheetCols[1])
if len(sheetCols[0]) >= len(sheetCols[1]) {
nLow = len(sheetCols[1])
nMax = len(sheetCols[0])
}
return nLow, nMax
}
func isExistingProduct(productName string) bool {
if productName == "" {
return true
}
// 实现商品名称是否存在的逻辑
var count int64
orm.Eloquent.Debug().Model(&ErpCommodity{}).
Where("name = ?", productName).
Count(&count)
return count > 0
}
func isExistingProductCode(productCode string) bool {
if productCode == "" {
return true
}
// 实现商品编号是否存在的逻辑
var count int64
orm.Eloquent.Debug().Model(&ErpCommodity{}).
Where("serial_number = ?", productCode).
Count(&count)
return count > 0
}
func isExistingStore(storeName string) bool {
// 实现门店是否存在的逻辑
var count int64
orm.Eloquent.Debug().Model(&Store{}).
Where("name = ?", storeName).
Count(&count)
return count > 0
}
func isExistingSupplier(supplierName string) bool {
// 实现供应商是否存在的逻辑
var count int64
orm.Eloquent.Debug().Model(&ErpSupplier{}).
Where("name = ?", supplierName).
Count(&count)
return count > 0
}
func checkSerialCode(productName, productCode, serialCode string) error {
var existingCommodity ErpCommodity
var queryCondition string
if productName != "" {
queryCondition = "name = ?"
} else if productCode != "" {
queryCondition = "serial_number = ?"
} else {
return errors.New("商品名称和商品编码不能都为空")
}
result := orm.Eloquent.Where(queryCondition, productName).Or(queryCondition, productCode).First(&existingCommodity)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return errors.New("未查询到商品数据")
}
fmt.Println("Error:", result.Error)
return result.Error
}
nIMEIType := int(existingCommodity.IMEIType)
if nIMEIType == 1 && serialCode != "" {
return errors.New("非串码商品,无需填写串码")
}
if nIMEIType != 1 && !isNumericOrAlpha(serialCode) {
return errors.New("串码类商品,请填写正确的串码")
}
return nil
}
func isNumericOrAlpha(s string) bool {
for _, char := range s {
if !unicode.IsDigit(char) && !unicode.IsLetter(char) {
return false
}
}
return true
}
// 将读取的excel数据转换成CategoryExcel struct // 将读取的excel数据转换成CategoryExcel struct
func transCategoryData(colsMap []map[string]interface{}) []CategoryExcel { func transCategoryData(colsMap []map[string]interface{}) []CategoryExcel {
var categories []CategoryExcel var categories []CategoryExcel
@ -441,6 +687,32 @@ func transCommodityData(colsMap []map[string]interface{}) ([]CommodityExcel, err
return commodities, nil return commodities, nil
} }
// 将读取的excel数据转换成CommodityExcel struct
func transStockData(colsMap []map[string]interface{}) ([]StockExcel, error) {
var stockInfos []StockExcel
// 遍历 colsMap 进行类型断言和转换
for _, col := range colsMap {
var stockInfo StockExcel
// 将 col 转换为 JSON 字符串
jsonData, err := json.Marshal(col)
if err != nil {
return nil, fmt.Errorf("failed to marshal data to JSON: %v", err)
}
// 将 JSON 字符串反序列化为 CommodityExcel
if err := json.Unmarshal(jsonData, &stockInfo); err != nil {
return nil, fmt.Errorf("failed to unmarshal JSON to StockExcel: %v", err)
}
// 将处理后的数据追加到 commodities 中
stockInfos = append(stockInfos, stockInfo)
}
return stockInfos, nil
}
func convertToErpCommodities(data []CommodityExcel) ([]ErpCommodity, error) { func convertToErpCommodities(data []CommodityExcel) ([]ErpCommodity, error) {
var erpCommodities []ErpCommodity var erpCommodities []ErpCommodity

View File

@ -1,7 +1,13 @@
package models package models
import ( import (
"errors"
"github.com/codinl/go-logger"
"github.com/gin-gonic/gin"
orm "go-admin/common/global" orm "go-admin/common/global"
"net"
"net/http"
"strings"
) )
type SysSetting struct { type SysSetting struct {
@ -15,7 +21,7 @@ func (SysSetting) TableName() string {
return "sys_setting" return "sys_setting"
} }
//查询 // 查询
func (s *SysSetting) Get() (create SysSetting, err error) { func (s *SysSetting) Get() (create SysSetting, err error) {
result := orm.Eloquent.Table("sys_setting").First(&create) result := orm.Eloquent.Table("sys_setting").First(&create)
if result.Error != nil { if result.Error != nil {
@ -25,7 +31,7 @@ func (s *SysSetting) Get() (create SysSetting, err error) {
return create, nil return create, nil
} }
//修改 // 修改
func (s *SysSetting) Update() (update SysSetting, err error) { func (s *SysSetting) Update() (update SysSetting, err error) {
if err = orm.Eloquent.Table("sys_setting").Model(&update).Updates(&s).Error; err != nil { if err = orm.Eloquent.Table("sys_setting").Model(&update).Updates(&s).Error; err != nil {
return return
@ -37,3 +43,85 @@ type ResponseSystemConfig struct {
Name string `json:"name" binding:"required"` // 名称 Name string `json:"name" binding:"required"` // 名称
Logo string `json:"logo" binding:"required"` // 头像 Logo string `json:"logo" binding:"required"` // 头像
} }
const (
LoggingEventInventoryImport = "inventory_import"
LoggingEventCreateSupplier = "create_supplier"
LoggingEventEditSupplier = "edit_supplier"
)
type Logging struct {
Model
Machine string `json:"machine"`
StoreId uint32 `json:"store_id" gorm:"index"` // 门店id
StoreName string `json:"store_name"`
OperatorUid uint32 `json:"operator_uid" gorm:"index"`
Operator string `json:"operator"`
Function string `json:"function"`
Event string `json:"event"`
EventName string `json:"event_name"`
Ip string `json:"ip"`
}
func (m *Logging) Create(c *gin.Context) error {
defer func() {
if err := recover(); err != nil {
logger.Error("recover create logging err:", err)
return
}
}()
go func() {
if c != nil {
sysUser, err := GetSysUserByCtx(c)
if err != nil {
logger.Error("sys user err:", err)
//return err
}
ip, err := GetIP(c.Request)
if err != nil {
logger.Error("get ip err:", err)
}
m.Machine = c.Request.UserAgent()
m.StoreId = sysUser.StoreId
m.StoreName = sysUser.StoreName
m.OperatorUid = uint32(sysUser.UserId)
m.Operator = sysUser.NickName
m.Ip = ip
}
err := orm.Eloquent.Create(m).Error
if err != nil {
logger.Error("create logging err:", err)
return
}
}()
return nil
}
func GetIP(r *http.Request) (string, error) {
ip := r.Header.Get("X-Real-IP")
if net.ParseIP(ip) != nil {
return ip, nil
}
ip = r.Header.Get("X-Forward-For")
for _, i := range strings.Split(ip, ",") {
if net.ParseIP(i) != nil {
return i, nil
}
}
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return "", err
}
if net.ParseIP(ip) != nil {
return ip, nil
}
return "", errors.New("no valid ip found")
}

View File

@ -24,12 +24,11 @@ type User struct {
} }
type UserName struct { type UserName struct {
Username string `gorm:"size:64" json:"username"` Username string `gorm:"size:64" json:"username"` // 用户名
} }
type PassWord struct { type PassWord struct {
// 密码 Password string `gorm:"size:128" json:"password"` // 密码
Password string `gorm:"size:128" json:"password"`
} }
type LoginM struct { type LoginM struct {
@ -42,24 +41,24 @@ type SysUserId struct {
} }
type SysUserB struct { type SysUserB struct {
NickName string `gorm:"size:128" json:"nickName"` // 昵称 NickName string `gorm:"size:128" json:"nickName"` // 昵称
Phone string `gorm:"size:11" json:"phone"` // 手机号 Phone string `gorm:"size:11" json:"phone"` // 手机号
RoleId int `gorm:"" json:"roleId"` // 角色编码 RoleId int `gorm:"" json:"roleId"` // 角色编码
Salt string `gorm:"size:255" json:"salt"` // Salt string `gorm:"size:255" json:"salt"` //
Avatar string `gorm:"size:255" json:"avatar"` //头像 Avatar string `gorm:"size:255" json:"avatar"` // 头像
Sex string `gorm:"size:255" json:"sex"` //性别 Sex string `gorm:"size:255" json:"sex"` // 性别
Email string `gorm:"size:128" json:"email"` //邮箱 Email string `gorm:"size:128" json:"email"` // 邮箱
DeptId int `gorm:"" json:"deptId"` //部门编码 DeptId int `gorm:"" json:"deptId"` // 部门编码
PostId int `gorm:"" json:"postId"` //职位编码 PostId int `gorm:"" json:"postId"` // 职位编码
CreateBy string `gorm:"size:128" json:"createBy"` // CreateBy string `gorm:"size:128" json:"createBy"` //
UpdateBy string `gorm:"size:128" json:"updateBy"` // UpdateBy string `gorm:"size:128" json:"updateBy"` //
Remark string `gorm:"size:255" json:"remark"` //备注 Remark string `gorm:"size:255" json:"remark"` // 备注
Status string `gorm:"size:4;" json:"status"` Status string `gorm:"size:4;" json:"status"` // 状态
StoreId uint32 `json:"store_id"` // 门店id StoreId uint32 `json:"store_id"` // 门店id
StoreName string `json:"store_name"` // 门店id StoreName string `json:"store_name"` // 门店名称
CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id
CooperativeName string `json:"cooperative_name"` // 合作商名称 CooperativeName string `json:"cooperative_name"` // 合作商名称
AccountType uint32 `json:"account_type"` // 账号类型:1-管理端 AccountType uint32 `json:"account_type"` // 账号类型:1-管理端
BaseModel BaseModel
DataScope string `gorm:"-" json:"dataScope"` DataScope string `gorm:"-" json:"dataScope"`

View File

@ -86,7 +86,7 @@ const (
) )
const DateTimeFormat = "2006-01-02" const DateTimeFormat = "2006-01-02"
const TimeFormat = "2006-01-02 15:04:05" const TimeFormat = "2006-01-02 15_04_05"
const ( const (
ExportUrl = "https://dev.admin.deovo.com/load/export/" ExportUrl = "https://dev.admin.deovo.com/load/export/"

View File

@ -26,19 +26,6 @@ func registerActivityManageUnAuthRouter(v1 *gin.RouterGroup) {
// 需认证的路由代码 // 需认证的路由代码
func registerActivityManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerActivityManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//r := v1.Group("/syscategory").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// r.GET("/:id", syscategory.GetSysCategory)
// r.POST("", syscategory.InsertSysCategory)
// r.PUT("", syscategory.UpdateSysCategory)
// r.DELETE("/:id", syscategory.DeleteSysCategory)
//}
//
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
activityRouter := v1.Group("/activity").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) activityRouter := v1.Group("/activity").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{ {
activityRouter.POST("/redeem_code/send_user", activitymanage.RedeemCodeSendToUser) activityRouter.POST("/redeem_code/send_user", activitymanage.RedeemCodeSendToUser)

View File

@ -41,20 +41,6 @@ func registerCooperativeManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.Gi
// 无需认证的路由代码 // 无需认证的路由代码
func registerCooperativeManageUnAuthRouter(v1 *gin.RouterGroup) { func registerCooperativeManageUnAuthRouter(v1 *gin.RouterGroup) {
cooperativeBusiness := v1.Group("/cooperative") cooperativeBusiness := v1.Group("/cooperative")
//{
// cooperativeBusiness.POST("/list", cooperativemanage.CooperativeBusinessList) // 获取合作商列表
//cooperativeBusiness.POST("/add", cooperativemanage.CooperativeAdd) // 获取合作商
// cooperativeBusiness.POST("member_promotion/list", cooperativemanage.CooperativeMemberPromotionList) // 合作商推广会员列表
// cooperativeBusiness.POST("member_promotion_store/list", cooperativemanage.CooperativeMemberPromotionStoreList) // 合作商推广会员门店列表
// cooperativeBusiness.POST("member_promotion_day/list", cooperativemanage.CooperativeMemberPromotionDayList) // 合作商每天推广会员列表
// cooperativeBusiness.POST("member_promotion_store_day/list", cooperativemanage.CooperativeMemberPromotionStoreDayList) // 合作商每天门店推广会员列表
//
// cooperativeBusiness.POST("member_promotion/settle_info", cooperativemanage.CooperativeMemberPromotionSettleInfo) // 合作商推广会员结算详情
// cooperativeBusiness.POST("member_promotion/settle_confirm", cooperativemanage.CooperativeMemberPromotionSettleConfirm) // 合作商推广会员结算确认
// cooperativeBusiness.POST("member_promotion/settle/list", cooperativemanage.CooperativeMemberPromotionSettleList) // 合作商推广会员结算列表
// cooperativeBusiness.POST("member_promotion/settle_remit", cooperativemanage.CooperativeMemberPromotionSettleRemit) // 合作商推广会员结算打款
// cooperativeBusiness.POST("/member_list", cooperativemanage.CooperativePromotionMemberList) // 获取合作商会员列表
//}
cooperativeBusiness.POST("member_promotion/settle/list", cooperativemanage.CooperativeMemberPromotionSettleList) // 合作商推广会员结算列表 cooperativeBusiness.POST("member_promotion/settle/list", cooperativemanage.CooperativeMemberPromotionSettleList) // 合作商推广会员结算列表
cooperativeBusiness.POST("member_promotion_statistic/list", cooperativemanage.CooperativeMemberPromotionStatisticList) // 合作商推广会员统计列表 cooperativeBusiness.POST("member_promotion_statistic/list", cooperativemanage.CooperativeMemberPromotionStatisticList) // 合作商推广会员统计列表
} }

View File

@ -8,38 +8,10 @@ import (
// 需认证的路由代码 // 需认证的路由代码
func registerGoodsManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerGoodsManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//goods := v1.Group("/goods")
//gr := goods.Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// //r.POST("/search", goodsmanage.GetHotSearch)
// //gr.GET("/search", goodsmanage.GetHotSearch)
//}
//gs := goods.Group("/search")
//{
// gr.GET("/hot/list", goodsmanage.GetHotSearch)
// gs.POST("/hot/del", goodsmanage.HotSearchDel)
// gs.POST("/hot/add", goodsmanage.HotSearchAdd)
// gs.POST("/hot/modify", goodsmanage.HotSearchModify)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
} }
// 无需认证的路由代码 // 无需认证的路由代码
func registerGoodsManageUnAuthRouter(v1 *gin.RouterGroup) { func registerGoodsManageUnAuthRouter(v1 *gin.RouterGroup) {
//v1.GET("/goods", sysfiledir.GetSysFileDirList)
//r := v1.Group("/goods")
//{
// r.GET("/search", goodsmanage.GetHotSearch)
//}
goods := v1.Group("/goods") goods := v1.Group("/goods")
{ {
goods.POST("/list", goodsmanage.GameCardList) // 获取游戏列表 goods.POST("/list", goodsmanage.GameCardList) // 获取游戏列表

View File

@ -12,5 +12,6 @@ func registerInventoryManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJ
r.POST("list", inventorymanage.GetInventoryList) r.POST("list", inventorymanage.GetInventoryList)
r.POST("detail", inventorymanage.GetInventoryDetail) r.POST("detail", inventorymanage.GetInventoryDetail)
r.POST("delivery", inventorymanage.DeliveryCargo) // 出库 r.POST("delivery", inventorymanage.DeliveryCargo) // 出库
r.POST("print", inventorymanage.BatchPrint) // 出库 r.POST("print", inventorymanage.BatchPrint) // 批量打印
r.POST("import", inventorymanage.BatchImport)
} }

View File

@ -57,41 +57,4 @@ func registerMallManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid
// 无需认证的路由代码 // 无需认证的路由代码
func registerMallManageUnAuthRouter(v1 *gin.RouterGroup) { func registerMallManageUnAuthRouter(v1 *gin.RouterGroup) {
//v1.GET("/goods", sysfiledir.GetSysFileDirList)
//r := v1.Group("/goods")
//{
// r.GET("/search", goodsmanage.GetHotSearch)
//}
//mall := v1.Group("/mall")
//{
//
// mall.POST("cat/create", mallmanage.GoodsCatCreate) // 分类添加
// mall.POST("cat/list", mallmanage.GoodsCatList) // 分类列表
// mall.POST("cat/update", mallmanage.GoodsCatUpdate) // 分类修改
//
// mall.POST("spec/create", mallmanage.GoodsSpecCreate) // 规格添加
// mall.POST("spec/list", mallmanage.GoodsSpecList) // 规格列表添加
// mall.POST("spec/update", mallmanage.GoodsSpecUpdate) // 规格添加
//
// mall.POST("spec_value/create", mallmanage.SpecValueCreate) // 规格值添加
// mall.POST("spec_value/list", mallmanage.SpecValueList) // 规格值列表
// mall.POST("spec_value/update", mallmanage.SpecValueUpdate) // 规格值修改
//
//}
//
//goods := mall.Group("/goods")
//{
// // goods.POST("/create", mallmanage.GoodsCreate)
// // goods.POST("/list", mallmanage.GoodsList)
// // goods.POST("/edit", mallmanage.GoodsEdit)
// // goods.POST("/order/list", mallmanage.GoodsOrderList)
// // goods.POST("/order/detail", mallmanage.GoodsOrderDetail)
// // goods.POST("/order/deliver", mallmanage.GoodsOrderDeliver) // 发货
// // goods.POST("/user/vm_record", mallmanage.MallUserVmRecord)
// goods.POST("/attribute_add", mallmanage.GoodsAttributeAdd) // 添加规格
// goods.POST("/attribute_m_del", mallmanage.GoodsAttributeMDel) // 删除规格
//}
} }

View File

@ -9,26 +9,6 @@ import (
// 需认证的路由代码 // 需认证的路由代码
func registerOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//goods := v1.Group("/goods")
//gr := goods.Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// //r.POST("/search", goodsmanage.GetHotSearch)
// //gr.GET("/search", goodsmanage.GetHotSearch)
//}
//gs := goods.Group("/search")
//{
// gr.GET("/hot/list", goodsmanage.GetHotSearch)
// gs.POST("/hot/del", goodsmanage.HotSearchDel)
// gs.POST("/hot/add", goodsmanage.HotSearchAdd)
// gs.POST("/hot/modify", goodsmanage.HotSearchModify)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
order := v1.Group("/order") order := v1.Group("/order")
{ {
order.POST("/list", ordermanage.OrderList) // 订单列表 order.POST("/list", ordermanage.OrderList) // 订单列表
@ -38,12 +18,6 @@ func registerOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMi
// 无需认证的路由代码 // 无需认证的路由代码
func registerOrderManageUnAuthRouter(v1 *gin.RouterGroup) { func registerOrderManageUnAuthRouter(v1 *gin.RouterGroup) {
//v1.GET("/goods", sysfiledir.GetSysFileDirList)
//r := v1.Group("/goods")
//{
// r.GET("/search", goodsmanage.GetHotSearch)
//}
order := v1.Group("/order") order := v1.Group("/order")
{ {
//order.POST("/list", ordermanage.OrderList) // 订单列表 //order.POST("/list", ordermanage.OrderList) // 订单列表
@ -58,7 +32,6 @@ func registerOrderManageUnAuthRouter(v1 *gin.RouterGroup) {
order.POST("/fund_record/list", ordermanage.FundRecordList) // 物流单列表 order.POST("/fund_record/list", ordermanage.FundRecordList) // 物流单列表
//order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型 //order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型
} }
} }

View File

@ -18,14 +18,6 @@ func registerRecycleCardManageUnAuthRouter(v1 *gin.RouterGroup) {
recycleCardRouter.POST("config/update", recyclecardmanage.RecycleCardConfigUpdate) // 管理端 recycleCardRouter.POST("config/update", recyclecardmanage.RecycleCardConfigUpdate) // 管理端
recycleCardRouter.POST("config/info", recyclecardmanage.RecycleCardConfigInfo) // 管理端 recycleCardRouter.POST("config/info", recyclecardmanage.RecycleCardConfigInfo) // 管理端
recycleCardRouter.POST("order/retrieve", recyclecardmanage.RecycleCardOrderRetrieve) // 管理端 recycleCardRouter.POST("order/retrieve", recyclecardmanage.RecycleCardOrderRetrieve) // 管理端
//recycleCardRouter.POST("cassette_image/update", recyclecardmanage.RecycleCardOrderImageUpdate) // 管理端
//redeemCode.POST("/send_user", activity.RedeemCodeSendToUser)
//redeemCode.POST("/user_redeem_code/list", activitymanage.UserRedeemCodeList)
//redeemCode.POST("/user_coupon/list", activitymanage.UserCouponList)
//redeemCode.POST("/config", activitymanage.RenewalConfigInfo)
//redeemCode.POST("/config/update", activitymanage.RenewalConfigUpdate)
//redeemCode.POST("/statistic", activitymanage.UserMemberRenewalStatistic)
} }
} }
@ -34,29 +26,7 @@ func registerRecycleCardManageUnAuthRouter(v1 *gin.RouterGroup) {
func registerRecycleCardManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerRecycleCardManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
recycleCardRouter := v1.Group("/recycle_card").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) recycleCardRouter := v1.Group("/recycle_card").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{ {
//recycleCardRouter.POST("order/list", recyclecardmanage.RecycleCardOrderList)
//recycleCardRouter.POST("order/detail", recyclecardmanage.RecycleCardOrderDetail)
//recycleCardRouter.POST("order/check", recyclecardmanage.RecycleCardOrderCheck) // 管理端
recycleCardRouter.POST("cassette_image/update", recyclecardmanage.RecycleCardOrderImageUpdate) // 管理端 recycleCardRouter.POST("cassette_image/update", recyclecardmanage.RecycleCardOrderImageUpdate) // 管理端
recycleCardRouter.POST("order/list", recyclecardmanage.RecycleCardOrderList) recycleCardRouter.POST("order/list", recyclecardmanage.RecycleCardOrderList)
} }
//r := v1.Group("/syscategory").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// r.GET("/:id", syscategory.GetSysCategory)
// r.POST("", syscategory.InsertSysCategory)
// r.PUT("", syscategory.UpdateSysCategory)
// r.DELETE("/:id", syscategory.DeleteSysCategory)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
//activityRouter := v1.Group("/activity").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// activityRouter.POST("/redeem_code/send_user", activitymanage.RedeemCodeSendToUser)
//}
} }

View File

@ -12,7 +12,7 @@ var (
routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0) routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0)
) )
// 路由示例 // InitExamplesRouter 路由示例
func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine { func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine {
// 无需认证的路由 // 无需认证的路由

View File

@ -8,38 +8,10 @@ import (
// 需认证的路由代码 // 需认证的路由代码
func registerShareManageAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerShareManageAuthRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//shareCard := v1.Group("/share_card")
//shareCardAuth := shareCard.Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// //r.POST("/search", goodsmanage.GetHotSearch)
// //gr.GET("/search", goodsmanage.GetHotSearch)
//}
//gs := goods.Group("/search")
//{
// gr.GET("/hot/list", goodsmanage.GetHotSearch)
// gs.POST("/hot/del", goodsmanage.HotSearchDel)
// gs.POST("/hot/add", goodsmanage.HotSearchAdd)
// gs.POST("/hot/modify", goodsmanage.HotSearchModify)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
//shareCardAuth.POST("/card_issue/check", sharemanage.CardIssueCheck) // 共享卡用户问题卡检测
} }
// 无需认证的路由代码 // 无需认证的路由代码
func registerShareManageUnAuthRouter(v1 *gin.RouterGroup) { func registerShareManageUnAuthRouter(v1 *gin.RouterGroup) {
//v1.GET("/goods", sysfiledir.GetSysFileDirList)
//r := v1.Group("/goods")
//{
// r.GET("/search", goodsmanage.GetHotSearch)
//}
expressStatePush := v1.Group("/express") expressStatePush := v1.Group("/express")
{ {
expressStatePush.POST("/state_push", sharemanage.ExpressStatePush) // 物流状态推送 expressStatePush.POST("/state_push", sharemanage.ExpressStatePush) // 物流状态推送
@ -66,13 +38,6 @@ func registerShareManageUnAuthRouter(v1 *gin.RouterGroup) {
shareCard.POST("/card_issue/check", sharemanage.CardIssueCheck) // 共享卡用户问题卡检测 shareCard.POST("/card_issue/check", sharemanage.CardIssueCheck) // 共享卡用户问题卡检测
shareCard.POST("/card_issue/deliver", sharemanage.CardIssueDeliver) // 共享卡用户问题卡发货 shareCard.POST("/card_issue/deliver", sharemanage.CardIssueDeliver) // 共享卡用户问题卡发货
shareCard.POST("/function_unusual_card/list", sharemanage.IssueCardFunctionUnusualList) // 功能异常卡列表 shareCard.POST("/function_unusual_card/list", sharemanage.IssueCardFunctionUnusualList) // 功能异常卡列表
//order.POST("/revert_goods", ordermanage.RevertGoods) // 订单归还
//order.POST("express_company/list", ordermanage.ExpressCompanyList) // 物流公司列表
//order.POST("/modify", goodsmanage.GameCardModify) // 修改游戏
//order.POST("/del", ordermanage.OrderDel) // 订单删除
//order.POST("/refund", ordermanage.OrderRefund) // 订单退款
//order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型
} }
} }

View File

@ -8,38 +8,10 @@ import (
// 需认证的路由代码 // 需认证的路由代码
func registerStockManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerStockManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//goods := v1.Group("/goods")
//gr := goods.Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// //r.POST("/search", goodsmanage.GetHotSearch)
// //gr.GET("/search", goodsmanage.GetHotSearch)
//}
//gs := goods.Group("/search")
//{
// gr.GET("/hot/list", goodsmanage.GetHotSearch)
// gs.POST("/hot/del", goodsmanage.HotSearchDel)
// gs.POST("/hot/add", goodsmanage.HotSearchAdd)
// gs.POST("/hot/modify", goodsmanage.HotSearchModify)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
} }
// 无需认证的路由代码 // 无需认证的路由代码
func registerStockManageUnAuthRouter(v1 *gin.RouterGroup) { func registerStockManageUnAuthRouter(v1 *gin.RouterGroup) {
//v1.GET("/goods", sysfiledir.GetSysFileDirList)
//r := v1.Group("/goods")
//{
// r.GET("/search", goodsmanage.GetHotSearch)
//}
order := v1.Group("/stock") order := v1.Group("/stock")
{ {
order.POST("/list", stockmanage.GameCardGoodsStockInfoList) // 库存列表 order.POST("/list", stockmanage.GameCardGoodsStockInfoList) // 库存列表
@ -56,7 +28,6 @@ func registerStockManageUnAuthRouter(v1 *gin.RouterGroup) {
order.POST("/cannibalize_task/goods_list", stockmanage.CannibalizeTaskGameCardGoodsList) // order.POST("/cannibalize_task/goods_list", stockmanage.CannibalizeTaskGameCardGoodsList) //
order.POST("/cannibalize_task/del", stockmanage.CannibalizeTaskDel) // order.POST("/cannibalize_task/del", stockmanage.CannibalizeTaskDel) //
//order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型 //order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型
} }
} }

View File

@ -223,6 +223,7 @@ func registerRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddlewar
} }
} }
// 系统管理-系统用户
func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
sysuser := v1.Group("/sysUser").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) sysuser := v1.Group("/sysUser").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{ {

View File

@ -9,26 +9,6 @@ import (
// 需认证的路由代码 // 需认证的路由代码
func registerUserManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { func registerUserManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) {
//goods := v1.Group("/goods")
//gr := goods.Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// //r.POST("/search", goodsmanage.GetHotSearch)
// //gr.GET("/search", goodsmanage.GetHotSearch)
//}
//gs := goods.Group("/search")
//{
// gr.GET("/hot/list", goodsmanage.GetHotSearch)
// gs.POST("/hot/del", goodsmanage.HotSearchDel)
// gs.POST("/hot/add", goodsmanage.HotSearchAdd)
// gs.POST("/hot/modify", goodsmanage.HotSearchModify)
//}
//l := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
//{
// l.GET("/syscategoryList", syscategory.GetSysCategoryList)
//}
userInfo := v1.Group("/user_info").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) userInfo := v1.Group("/user_info").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole())
{ {
userInfo.POST("/list", usermanage.UserList) userInfo.POST("/list", usermanage.UserList)
@ -41,7 +21,6 @@ func registerUserManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid
func registerUserManageUnAuthRouter(v1 *gin.RouterGroup) { func registerUserManageUnAuthRouter(v1 *gin.RouterGroup) {
userInfo := v1.Group("/user_info") userInfo := v1.Group("/user_info")
{ {
userInfo.POST("/add_assistant", usermanage.UserAddAssistant) userInfo.POST("/add_assistant", usermanage.UserAddAssistant)
userInfo.POST("/assistant_del", usermanage.UserAssistantDel) userInfo.POST("/assistant_del", usermanage.UserAssistantDel)
userInfo.POST("/invite_list", usermanage.UserInviteList) userInfo.POST("/invite_list", usermanage.UserInviteList)

View File

@ -48,3 +48,9 @@ settings:
dbname: dbname dbname: dbname
# 代码生成是使用前端代码存放位置需要指定到src文件夹相对路径 # 代码生成是使用前端代码存放位置需要指定到src文件夹相对路径
frontpath: ../go-admin-ui/src frontpath: ../go-admin-ui/src
export:
path: D:\\
url: http://39.108.188.218:8000/img/export/
# path: /www/server/images/export/
# url: http://39.108.188.218:8000/img/export/

View File

@ -28,7 +28,10 @@ var cfgSsl *viper.Viper
// 代码生成配置项 非必须 // 代码生成配置项 非必须
var cfgGen *viper.Viper var cfgGen *viper.Viper
//载入配置文件 // 代码生成配置项 非必须
var cfgExport *viper.Viper
// 载入配置文件
func Setup(path string) { func Setup(path string) {
viper.SetConfigFile(path) viper.SetConfigFile(path)
content, err := ioutil.ReadFile(path) content, err := ioutil.ReadFile(path)
@ -81,4 +84,10 @@ func Setup(path string) {
panic("No found settings.gen") panic("No found settings.gen")
} }
GenConfig = InitGen(cfgGen) GenConfig = InitGen(cfgGen)
cfgExport = viper.Sub("settings.export")
if cfgExport == nil {
panic("No found settings.export")
}
ExportConfig = InitExport(cfgExport)
} }

19
tools/config/export.go Normal file
View File

@ -0,0 +1,19 @@
package config
import "github.com/spf13/viper"
type Export struct {
Path string
Url string
}
func InitExport(cfg *viper.Viper) *Export {
db := &Export{
Path: cfg.GetString("path"),
Url: cfg.GetString("url"),
}
return db
}
var ExportConfig = new(Export)