diff --git a/app/admin/apis/inventorymanage/Inventory.go b/app/admin/apis/inventorymanage/Inventory.go index 4fdc41e..bb2d5a3 100644 --- a/app/admin/apis/inventorymanage/Inventory.go +++ b/app/admin/apis/inventorymanage/Inventory.go @@ -2,10 +2,12 @@ package inventorymanage import ( "errors" + "fmt" "github.com/gin-gonic/gin" "go-admin/app/admin/models" "go-admin/tools" "go-admin/tools/app" + "io" "net/http" ) @@ -131,3 +133,173 @@ func BatchPrint(c *gin.Context) { app.OK(c, nil, "OK") 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 +} diff --git a/app/admin/models/commodity.go b/app/admin/models/commodity.go index fe446b1..4bcac9d 100644 --- a/app/admin/models/commodity.go +++ b/app/admin/models/commodity.go @@ -6,6 +6,7 @@ import ( "github.com/xuri/excelize/v2" orm "go-admin/common/global" "go-admin/logger" + "go-admin/tools/config" "golang.org/x/sync/errgroup" "gorm.io/gorm" "strconv" @@ -14,9 +15,7 @@ import ( "time" ) -// ErpStock 库存表 -// -//go:generate goqueryset -in commodity.go +// ErpStock 库存列表 type ErpStock struct { Model @@ -66,6 +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:"-"` // 备注 //Commodity ErpCommodity `json:"commodity" gorm:"-"` } @@ -95,7 +95,7 @@ type ErpCommodity struct { ErpCategory *ErpCategory `json:"erp_category" gorm:"-"` } -// gen:qs +// ErpCategory 商品分类 type ErpCategory struct { Model @@ -111,7 +111,7 @@ type ErpCategory struct { // erp_category } -// gen:qs +// ErpSupplier 供应商 type ErpSupplier struct { Model @@ -131,7 +131,6 @@ type ErpSupplier struct { // erp_supplier } -// gen:qs type ErpInventoryStock struct { Model @@ -156,7 +155,6 @@ type ErpInventoryStock struct { // erp_inventory_stock } -// gen:qs type ErpInventoryStockCommodity struct { Model @@ -183,6 +181,7 @@ type ErpInventoryStockCommodity struct { // erp_inventory_stock_commodity } +// IdInit 新增/编辑商品时获取分类和供应商信息 func (c *ErpCommodity) IdInit() { if c.ErpCategoryId != 0 { if c.ErpCategory == nil { @@ -206,6 +205,7 @@ func (c *ErpCommodity) IdInit() { } } +// GetErpCategory 根据id查询分类信息 func GetErpCategory(id uint32) (*ErpCategory, error) { category := new(ErpCategory) 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 } +// GetErpSupplier 根据id查询供应商 func GetErpSupplier(id uint32) (*ErpSupplier, error) { supplier := new(ErpSupplier) 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 } +// SetErpCategory 新增/编辑商品时设置分类信息 func (c *ErpCommodity) SetErpCategory() error { if c.ErpCategoryId != 0 { category, err := GetErpCategory(c.ErpCategoryId) @@ -537,99 +539,6 @@ func (m *CommodityNumberCount) GetErpCommodityNumberByCategoryId(categoryId uint 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 { List []ErpSupplier `json:"list"` Total int `json:"total"` @@ -638,11 +547,6 @@ type ErpSupplierListResp struct { 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 EsStockLock sync.Mutex @@ -659,9 +563,9 @@ type ErpStockFileExcel struct { 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"` - CountString string `json:"count_string"` + StaffCostPriceString string `json:"staff_cost_price_string"` // 员工成本价加价 + WholesalePriceString string `json:"wholesale_price_string"` // 指导采购价 + CountString string `json:"count_string"` // 数量 //StoreName string `json:"store_name"` //ErpCommodityName string `json:"erp_commodity_name"` @@ -674,15 +578,6 @@ type ErpStockFileExcel struct { 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() { e.Count = IntStringToUin32(e.CountString) if e.IsIMEI == "是" { @@ -709,51 +604,41 @@ func (e *ErpStockFileExcel) Processing() { } -func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel) error { - //allCategoriesMap, err := GetErpCategorySubMap() - //if err != nil { - // logger.Error("all categories map err:", err) - // return - //} - // 加锁 - //m.CensusMap = make(map[uint32]map[uint32]uint32, 0) +func (m *StockImporter) ImportStockData2(colsMap []map[string]interface{}) error { + list, err := transStockData(colsMap) + if err != nil { + return err + } + + var erpStockCommodity []ErpStockCommodity storeNameMap := make(map[string]uint32, 0) erpCommodityMap := make(map[string]*ErpCommodity, 0) - erpCategoryNameMap := make(map[string]uint32, 0) erpSupplierNameMap := make(map[string]uint32, 0) storeNames := make([]string, 0, len(list)) erpCommodityNames := make([]string, 0, len(list)) - erpCategoryNames := make([]string, 0, len(list)) erpSupplierNames := make([]string, 0, len(list)) for i, _ := range list { - list[i].Processing() _, ok1 := storeNameMap[list[i].StoreName] if !ok1 { storeNames = append(storeNames, list[i].StoreName) } - _, ok2 := erpCommodityMap[list[i].ErpCommodityName] + _, ok2 := erpCommodityMap[list[i].Name] 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 { - erpCategoryNames = append(erpCategoryNames, list[i].ErpCategoryName) - } - _, ok4 := erpSupplierNameMap[list[i].ErpSupplierName] - if !ok4 { - erpSupplierNames = append(erpSupplierNames, list[i].ErpSupplierName) + erpSupplierNames = append(erpSupplierNames, list[i].SupplierName) } storeNameMap[list[i].StoreName] = uint32(0) - erpCommodityMap[list[i].ErpCommodityName] = nil - erpCategoryNameMap[list[i].ErpCategoryName] = uint32(0) - erpSupplierNameMap[list[i].ErpSupplierName] = 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 + err = orm.Eloquent.Table("store").Where("name IN (?)", storeNames).Find(&stores).Error if err != nil { //logger.Error("stores err:", err) return err @@ -766,16 +651,9 @@ func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel 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 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) return err } @@ -790,76 +668,287 @@ func (m *StockImporter) ErpStockFileExcelListProcessing(list []ErpStockFileExcel m.CommodityMap[erpCommodities[i].ID] = &erpCommodities[i] } - for i, _ := range erpCategories { - erpCategoryNameMap[erpCategories[i].Name] = erpCategories[i].ID + 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") + 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 { 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() + //erpStockCommodity := make([]ErpStockCommodity, 0, len(list)) for i, _ := range list { 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 { 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") - return errors.New("erp commodity name err") + return nil, errors.New("erp commodity name err") } + + v3, ok3 := erpSupplierNameMap[list[i].SupplierName] if !ok3 { - logger.Error("erp category name err") - return errors.New("erp category name err") - } - if !ok4 { 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 - list[i].CommoditySerialNumber = v2.SerialNumber - list[i].ErpCategoryId = v3 - list[i].ErpSupplierId = v4 - list[i].State = 1 - list[i].StorageType = 1 - list[i].FirstStockTime = nowTime + // 注意:表格导入是员工成本价,数据库存储是员工成本价加价=员工成本价-指导采购价 + 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("导入价格有误,员工成本价低于指导采购价") + } - //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] - if ok5 { - m.CensusMap[list[i].StoreId][list[i].ErpCommodityId] += list[i].Count + 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[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 { @@ -929,7 +1018,7 @@ func (m *StockImporter) ErpStockCountUpdate(gdb *gorm.DB) error { return nil } -func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockFileExcel) error { +func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockCommodity) error { defer func() { if err := recover(); err != nil { //logger.Error("err:", err) @@ -991,53 +1080,10 @@ func (m *StockImporter) ErpInventoryStockCreate(gdb *gorm.DB, list []ErpStockFil 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 } -func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []ErpStockFileExcel) []*ErpInventoryStockCommodity { +func ErpStockCommodityToInventory(inventoryStockIdMap map[string]uint32, list []ErpStockCommodity) []*ErpInventoryStockCommodity { inventoryList := make([]*ErpInventoryStockCommodity, 0, len(list)) for i, _ := range list { 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 } +// ErpCommodityListExport 导出商品列表 func ErpCommodityListExport(list []ErpCommodity) (string, error) { file := excelize.NewFile() streamWriter, err := file.NewStreamWriter("Sheet1") @@ -1113,6 +1160,82 @@ func ErpCommodityListExport(list []ErpCommodity) (string, error) { 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) { file := excelize.NewFile() streamWriter, err := file.NewStreamWriter("Sheet1") @@ -1166,6 +1289,7 @@ type ErpStockListReq struct { PageSize int `json:"page_size"` // 页码 //IsExport uint32 `json:"is_export"` // 1-导出 } + type ErpStockListResp struct { List []ErpStock `json:"list"` 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 库存详情接口请求参数 type ErpStockCommodityListReq struct { ErpStockId uint32 `json:"erp_stock_id"` // 库存id @@ -1303,11 +1419,11 @@ func (m *ErpStockCommodityListReq) GetDetailList() (*ErpStockCommodityListResp, return resp, err } - //listExport, err := ErpCommodityListExport(commodities) - //if err != nil { - // logger.Error("list export err:", err) - //} - //resp.ExportUrl = listExport + listExport, err := InventoryDetailListExport(commodities) + if err != nil { + //logger.Error("list export err:", err) + } + resp.ExportUrl = listExport } else { err := qs.Offset(page * m.PageSize).Limit(m.PageSize).Find(&commodities).Error if err != nil && !errors.Is(err, RecordNotFound) { @@ -1424,3 +1540,18 @@ 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 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), + } +} diff --git a/app/admin/models/file.go b/app/admin/models/file.go index 00ed70e..8c5953f 100644 --- a/app/admin/models/file.go +++ b/app/admin/models/file.go @@ -13,6 +13,8 @@ import ( "reflect" "strconv" "strings" + "time" + "unicode" ) type CategoryExcel struct { @@ -38,6 +40,18 @@ type CommodityExcel struct { 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导入数据 func getJSONTagNames(s interface{}) []string { valueType := reflect.TypeOf(s) @@ -90,6 +104,8 @@ func FileExcelReader(d []byte, cols []string) ([]byte, []map[string]interface{}, cols = getJSONTagNames(CategoryExcel{}) case "导商品": cols = getJSONTagNames(CommodityExcel{}) + case "导库存": + cols = getJSONTagNames(StockExcel{}) default: cols = make([]string, len(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{} if len(cols) == 0 { - switch nType { // 导入类型:1 商品分类 2 商品资料 + switch nType { // 导入类型:1 商品分类 2 商品资料 3 商品库存 case 1: if sheetList[0] != "导分类" { 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 } 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: return nil, nil, errors.New("格式错误,不是商品分类或资料模版excel") } @@ -273,6 +297,228 @@ func checkCommodityExcel(sheetCols [][]string) error { 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 func transCategoryData(colsMap []map[string]interface{}) []CategoryExcel { var categories []CategoryExcel @@ -441,6 +687,32 @@ func transCommodityData(colsMap []map[string]interface{}) ([]CommodityExcel, err 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) { var erpCommodities []ErpCommodity diff --git a/app/admin/models/system.go b/app/admin/models/system.go index ec94125..1f5de3b 100644 --- a/app/admin/models/system.go +++ b/app/admin/models/system.go @@ -1,7 +1,13 @@ package models import ( + "errors" + "github.com/codinl/go-logger" + "github.com/gin-gonic/gin" orm "go-admin/common/global" + "net" + "net/http" + "strings" ) type SysSetting struct { @@ -15,7 +21,7 @@ func (SysSetting) TableName() string { return "sys_setting" } -//查询 +// 查询 func (s *SysSetting) Get() (create SysSetting, err error) { result := orm.Eloquent.Table("sys_setting").First(&create) if result.Error != nil { @@ -25,7 +31,7 @@ func (s *SysSetting) Get() (create SysSetting, err error) { return create, nil } -//修改 +// 修改 func (s *SysSetting) Update() (update SysSetting, err error) { if err = orm.Eloquent.Table("sys_setting").Model(&update).Updates(&s).Error; err != nil { return @@ -37,3 +43,85 @@ type ResponseSystemConfig struct { Name string `json:"name" 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") +} diff --git a/app/admin/models/sysuser.go b/app/admin/models/sysuser.go index 029d562..ecd8fb7 100644 --- a/app/admin/models/sysuser.go +++ b/app/admin/models/sysuser.go @@ -24,12 +24,11 @@ type User struct { } type UserName struct { - Username string `gorm:"size:64" json:"username"` + Username string `gorm:"size:64" json:"username"` // 用户名 } type PassWord struct { - // 密码 - Password string `gorm:"size:128" json:"password"` + Password string `gorm:"size:128" json:"password"` // 密码 } type LoginM struct { @@ -42,24 +41,24 @@ type SysUserId struct { } type SysUserB struct { - NickName string `gorm:"size:128" json:"nickName"` // 昵称 - Phone string `gorm:"size:11" json:"phone"` // 手机号 - RoleId int `gorm:"" json:"roleId"` // 角色编码 - Salt string `gorm:"size:255" json:"salt"` //盐 - Avatar string `gorm:"size:255" json:"avatar"` //头像 - Sex string `gorm:"size:255" json:"sex"` //性别 - Email string `gorm:"size:128" json:"email"` //邮箱 - DeptId int `gorm:"" json:"deptId"` //部门编码 - PostId int `gorm:"" json:"postId"` //职位编码 - CreateBy string `gorm:"size:128" json:"createBy"` // - UpdateBy string `gorm:"size:128" json:"updateBy"` // - Remark string `gorm:"size:255" json:"remark"` //备注 - Status string `gorm:"size:4;" json:"status"` - StoreId uint32 `json:"store_id"` // 门店id - StoreName string `json:"store_name"` // 门店id - CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` - CooperativeName string `json:"cooperative_name"` // 合作商名称 - AccountType uint32 `json:"account_type"` // 账号类型:1-管理端 + NickName string `gorm:"size:128" json:"nickName"` // 昵称 + Phone string `gorm:"size:11" json:"phone"` // 手机号 + RoleId int `gorm:"" json:"roleId"` // 角色编码 + Salt string `gorm:"size:255" json:"salt"` // 盐 + Avatar string `gorm:"size:255" json:"avatar"` // 头像 + Sex string `gorm:"size:255" json:"sex"` // 性别 + Email string `gorm:"size:128" json:"email"` // 邮箱 + DeptId int `gorm:"" json:"deptId"` // 部门编码 + PostId int `gorm:"" json:"postId"` // 职位编码 + CreateBy string `gorm:"size:128" json:"createBy"` // + UpdateBy string `gorm:"size:128" json:"updateBy"` // + Remark string `gorm:"size:255" json:"remark"` // 备注 + Status string `gorm:"size:4;" json:"status"` // 状态 + StoreId uint32 `json:"store_id"` // 门店id + StoreName string `json:"store_name"` // 门店名称 + CooperativeBusinessId uint32 `json:"cooperative_business_id" gorm:"index"` // 合作商id + CooperativeName string `json:"cooperative_name"` // 合作商名称 + AccountType uint32 `json:"account_type"` // 账号类型:1-管理端 BaseModel DataScope string `gorm:"-" json:"dataScope"` diff --git a/app/admin/models/user.go b/app/admin/models/user.go index 7f25e52..f311282 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/activitymanage.go b/app/admin/router/activitymanage.go index 13842ef..1fdb263 100644 --- a/app/admin/router/activitymanage.go +++ b/app/admin/router/activitymanage.go @@ -26,19 +26,6 @@ func registerActivityManageUnAuthRouter(v1 *gin.RouterGroup) { // 需认证的路由代码 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.POST("/redeem_code/send_user", activitymanage.RedeemCodeSendToUser) diff --git a/app/admin/router/cooperativemanage.go b/app/admin/router/cooperativemanage.go index a5af22f..4ce5c2c 100644 --- a/app/admin/router/cooperativemanage.go +++ b/app/admin/router/cooperativemanage.go @@ -41,20 +41,6 @@ func registerCooperativeManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.Gi // 无需认证的路由代码 func registerCooperativeManageUnAuthRouter(v1 *gin.RouterGroup) { 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_statistic/list", cooperativemanage.CooperativeMemberPromotionStatisticList) // 合作商推广会员统计列表 } diff --git a/app/admin/router/goodsmanage.go b/app/admin/router/goodsmanage.go index ee9baba..b2c4e5d 100644 --- a/app/admin/router/goodsmanage.go +++ b/app/admin/router/goodsmanage.go @@ -8,38 +8,10 @@ import ( // 需认证的路由代码 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) { - - //v1.GET("/goods", sysfiledir.GetSysFileDirList) - //r := v1.Group("/goods") - //{ - // r.GET("/search", goodsmanage.GetHotSearch) - //} - goods := v1.Group("/goods") { goods.POST("/list", goodsmanage.GameCardList) // 获取游戏列表 diff --git a/app/admin/router/inventory.go b/app/admin/router/inventory.go index 7d7926d..12ab4df 100644 --- a/app/admin/router/inventory.go +++ b/app/admin/router/inventory.go @@ -12,5 +12,6 @@ func registerInventoryManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJ r.POST("list", inventorymanage.GetInventoryList) r.POST("detail", inventorymanage.GetInventoryDetail) r.POST("delivery", inventorymanage.DeliveryCargo) // 出库 - r.POST("print", inventorymanage.BatchPrint) // 出库 + r.POST("print", inventorymanage.BatchPrint) // 批量打印 + r.POST("import", inventorymanage.BatchImport) } diff --git a/app/admin/router/mallmanage.go b/app/admin/router/mallmanage.go index add8e36..4e0e73b 100644 --- a/app/admin/router/mallmanage.go +++ b/app/admin/router/mallmanage.go @@ -57,41 +57,4 @@ func registerMallManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid // 无需认证的路由代码 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) // 删除规格 - //} - } diff --git a/app/admin/router/ordermanage.go b/app/admin/router/ordermanage.go index 9384b4f..77ea789 100644 --- a/app/admin/router/ordermanage.go +++ b/app/admin/router/ordermanage.go @@ -9,26 +9,6 @@ import ( // 需认证的路由代码 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.POST("/list", ordermanage.OrderList) // 订单列表 @@ -38,12 +18,6 @@ func registerOrderManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMi // 无需认证的路由代码 func registerOrderManageUnAuthRouter(v1 *gin.RouterGroup) { - //v1.GET("/goods", sysfiledir.GetSysFileDirList) - //r := v1.Group("/goods") - //{ - // r.GET("/search", goodsmanage.GetHotSearch) - //} - order := v1.Group("/order") { //order.POST("/list", ordermanage.OrderList) // 订单列表 @@ -58,7 +32,6 @@ func registerOrderManageUnAuthRouter(v1 *gin.RouterGroup) { order.POST("/fund_record/list", ordermanage.FundRecordList) // 物流单列表 //order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型 - } } diff --git a/app/admin/router/recyclecardmanage.go b/app/admin/router/recyclecardmanage.go index 4e39fa3..f26d138 100644 --- a/app/admin/router/recyclecardmanage.go +++ b/app/admin/router/recyclecardmanage.go @@ -18,14 +18,6 @@ func registerRecycleCardManageUnAuthRouter(v1 *gin.RouterGroup) { recycleCardRouter.POST("config/update", recyclecardmanage.RecycleCardConfigUpdate) // 管理端 recycleCardRouter.POST("config/info", recyclecardmanage.RecycleCardConfigInfo) // 管理端 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) { 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("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) - //} - } diff --git a/app/admin/router/router.go b/app/admin/router/router.go index 1784de3..845ef57 100644 --- a/app/admin/router/router.go +++ b/app/admin/router/router.go @@ -12,7 +12,7 @@ var ( routerCheckRole = make([]func(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware), 0) ) -// 路由示例 +// InitExamplesRouter 路由示例 func InitExamplesRouter(r *gin.Engine, authMiddleware *jwt.GinJWTMiddleware) *gin.Engine { // 无需认证的路由 diff --git a/app/admin/router/sharemanage.go b/app/admin/router/sharemanage.go index 2984dac..5843ba6 100644 --- a/app/admin/router/sharemanage.go +++ b/app/admin/router/sharemanage.go @@ -8,38 +8,10 @@ import ( // 需认证的路由代码 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) { - - //v1.GET("/goods", sysfiledir.GetSysFileDirList) - //r := v1.Group("/goods") - //{ - // r.GET("/search", goodsmanage.GetHotSearch) - //} expressStatePush := v1.Group("/express") { 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/deliver", sharemanage.CardIssueDeliver) // 共享卡用户问题卡发货 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) // 获取游戏类型 - } } diff --git a/app/admin/router/stockmanage.go b/app/admin/router/stockmanage.go index 76edde5..3f5296c 100644 --- a/app/admin/router/stockmanage.go +++ b/app/admin/router/stockmanage.go @@ -8,38 +8,10 @@ import ( // 需认证的路由代码 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) { - - //v1.GET("/goods", sysfiledir.GetSysFileDirList) - //r := v1.Group("/goods") - //{ - // r.GET("/search", goodsmanage.GetHotSearch) - //} - order := v1.Group("/stock") { 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/del", stockmanage.CannibalizeTaskDel) // //order.POST("/type", goodsmanage.GameCardTypes) // 获取游戏类型 - } } diff --git a/app/admin/router/sysrouter.go b/app/admin/router/sysrouter.go index ba48f68..54ab2fa 100644 --- a/app/admin/router/sysrouter.go +++ b/app/admin/router/sysrouter.go @@ -223,6 +223,7 @@ func registerRoleRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddlewar } } +// 系统管理-系统用户 func registerSysUserRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { sysuser := v1.Group("/sysUser").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) { diff --git a/app/admin/router/usermanage.go b/app/admin/router/usermanage.go index 426ead2..114aa1e 100644 --- a/app/admin/router/usermanage.go +++ b/app/admin/router/usermanage.go @@ -9,26 +9,6 @@ import ( // 需认证的路由代码 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.POST("/list", usermanage.UserList) @@ -41,7 +21,6 @@ func registerUserManageRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMid func registerUserManageUnAuthRouter(v1 *gin.RouterGroup) { userInfo := v1.Group("/user_info") { - userInfo.POST("/add_assistant", usermanage.UserAddAssistant) userInfo.POST("/assistant_del", usermanage.UserAssistantDel) userInfo.POST("/invite_list", usermanage.UserInviteList) diff --git a/config/settings.yml b/config/settings.yml index 21a38b1..fd75b4f 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -48,3 +48,9 @@ settings: dbname: dbname # 代码生成是使用前端代码存放位置,需要指定到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/ diff --git a/tools/config/config.go b/tools/config/config.go index 62c6b92..b3e53eb 100644 --- a/tools/config/config.go +++ b/tools/config/config.go @@ -28,7 +28,10 @@ var cfgSsl *viper.Viper // 代码生成配置项 非必须 var cfgGen *viper.Viper -//载入配置文件 +// 代码生成配置项 非必须 +var cfgExport *viper.Viper + +// 载入配置文件 func Setup(path string) { viper.SetConfigFile(path) content, err := ioutil.ReadFile(path) @@ -81,4 +84,10 @@ func Setup(path string) { panic("No found settings.gen") } GenConfig = InitGen(cfgGen) + + cfgExport = viper.Sub("settings.export") + if cfgExport == nil { + panic("No found settings.export") + } + ExportConfig = InitExport(cfgExport) } diff --git a/tools/config/export.go b/tools/config/export.go new file mode 100644 index 0000000..f967d26 --- /dev/null +++ b/tools/config/export.go @@ -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)