package model import ( "encoding/csv" "fmt" "github.com/codinl/go-logger" "github.com/xuri/excelize/v2" "os" "time" ) type ExportGoods struct { GoodsName string `json:"goods_name"` CardPool uint32 `json:"card_pool"` RentStock uint32 `json:"rent_stock"` PlayerHold uint32 `json:"player_hold"` OrderCount uint32 `json:"order_count"` DelayDeliverGameCard uint32 `json:"delay_deliver_game_card"` Goods []GameCardGoods `json:"goods"` } func ExportGoodsStock(storeId uint32) string { var games []GameCard err := DB.Table("game_card").Order("id DESC").Find(&games).Error if err != nil { logger.Error("err:", err) return "" } if storeId == 0 { allInfo, err := GoodsStockAllInfo(games) if err != nil { logger.Error("err:", err) return "" } return GoodsStockFile(allInfo, "全部门店") } else { var store Store err := DB.Table("store").Where("id=?", storeId).Find(&store).Error if err != nil { logger.Error("err:", err) return "" } storeInfo, err := GoodsStockStoreInfo(games, storeId) if err != nil { logger.Error("err:", err) return "" } return GoodsStockFile(storeInfo, store.Name) } } func GoodsStockAllInfo(gameCards []GameCard) ([]ExportGoods, error) { goodsData := make([]ExportGoods, 0, len(gameCards)) cardStocks := make([]GameCardGoodsStock, 0) err := DB.Table("game_card_goods_stock").Order("id DESC").Find(&cardStocks).Error if err != nil { logger.Error("err:", err) return goodsData, err } cardStockMap := make(map[uint64][]GameCardGoodsStock, 0) for i, _ := range cardStocks { cardStockMap[cardStocks[i].GameCardId] = append(cardStockMap[cardStocks[i].GameCardId], cardStocks[i]) } cardGoods := make([]GameCardGoods, 0) err = DB.Table("game_card_goods").Order("id DESC").Find(&cardGoods).Error if err != nil { logger.Error("err:", err) return goodsData, err } cardGoodsMap := make(map[uint64][]GameCardGoods, 0) for i, _ := range cardGoods { cardGoodsMap[cardGoods[i].GameCardId] = append(cardGoodsMap[cardGoods[i].GameCardId], cardGoods[i]) } for _, game := range gameCards { cardStock, ok1 := cardStockMap[uint64(game.ID)] gameCardGoods, ok2 := cardGoodsMap[uint64(game.ID)] if !ok1 || !ok2 { continue } exportGoods := &ExportGoods{ GoodsName: game.Name, Goods: gameCardGoods, } for i, _ := range cardStock { exportGoods.RentStock += cardStock[i].RentStock exportGoods.OrderCount += cardStock[i].OrderCount } exportGoods.CardPool = uint32(len(gameCardGoods)) for i, _ := range gameCardGoods { if gameCardGoods[i].Status == GameCardGoodsStatusCustomerHold { exportGoods.PlayerHold += 1 } } exportGoods.DelayDeliverGameCard = uint32(len(gameCardGoods)) - exportGoods.RentStock - exportGoods.PlayerHold goodsData = append(goodsData, *exportGoods) } return goodsData, err } func GoodsStockFile(goodsData []ExportGoods, fileName string) string { url := "http://switch.deovo.com:8000/img/export/" fileName = fileName + time.Now().Format("2006-01-02 15:04:05") + ".csv" // /www/server/images/export //f, err := os.OpenFile(fmt.Sprintf("./")+fileName, os.O_CREATE|os.O_TRUNC|os.O_APPEND|os.O_RDWR, 0644) f, err := os.OpenFile(fmt.Sprintf("/www/server/images/export/")+fileName, os.O_CREATE|os.O_TRUNC|os.O_APPEND|os.O_RDWR, 0644) if err != nil { fmt.Println(err) return url + fileName } defer f.Close() w := csv.NewWriter(f) headline := []string{"游戏名称", "卡池总数", "在库数量", "玩家持有数量", "锁定数量", "借出总数", "游戏卡编号", "状态"} if err := w.Write(headline); err != nil { logger.Error("error writing record to csv:", err) return url } for _, goods := range goodsData { record := []string{goods.GoodsName, fmt.Sprintf("%d", goods.CardPool), fmt.Sprintf("%d", goods.RentStock), fmt.Sprintf("%d", goods.PlayerHold), fmt.Sprintf("%d", goods.DelayDeliverGameCard), fmt.Sprintf("%d", goods.OrderCount)} if len(goods.Goods) > 0 { record = append(record, goods.Goods[0].SerialNumber, GoodsStatusStringByStatus(goods.Goods[0].Status)) } if err := w.Write(record); err != nil { logger.Error("error writing record to csv:", err) return url } if len(goods.Goods) <= 1 { continue } for _, cardGoods := range goods.Goods[1:] { recordGoods := make([]string, 6) recordGoods = append(recordGoods, cardGoods.SerialNumber, GoodsStatusStringByStatus(cardGoods.Status)) if err := w.Write(recordGoods); err != nil { logger.Error("error writing record to csv:", err) return url } } } newFile := excelize.NewFile() fmt.Println("newFile:", newFile) w.Flush() if err := w.Error(); err != nil { //log.Fatal(err) logger.Error("err:", err) } return url + fileName } func GoodsStockStoreInfo(gameCards []GameCard, storeId uint32) ([]ExportGoods, error) { goodsData := make([]ExportGoods, 0, len(gameCards)) cardStocks := make([]GameCardGoodsStock, 0) err := DB.Table("game_card_goods_stock").Where("store_id=?", storeId).Order("id DESC").Find(&cardStocks).Error if err != nil { logger.Error("err:", err) return goodsData, err } cardStockMap := make(map[uint64]GameCardGoodsStock, 0) for i, _ := range cardStocks { cardStockMap[cardStocks[i].GameCardId] = cardStocks[i] } cardGoods := make([]GameCardGoods, 0) err = DB.Table("game_card_goods").Where("store_id=?", storeId).Order("id DESC").Find(&cardGoods).Error if err != nil { logger.Error("err:", err) return goodsData, err } cardGoodsMap := make(map[uint64][]GameCardGoods, 0) for i, _ := range cardGoods { cardGoodsMap[cardGoods[i].GameCardId] = append(cardGoodsMap[cardGoods[i].GameCardId], cardGoods[i]) } for _, game := range gameCards { cardStock, ok1 := cardStockMap[uint64(game.ID)] gameCardGoods, ok2 := cardGoodsMap[uint64(game.ID)] if !ok1 || !ok2 { continue } exportGoods := &ExportGoods{ GoodsName: game.Name, //CardPool: cardStock.StoreStock, RentStock: cardStock.RentStock, OrderCount: cardStock.OrderCount, Goods: gameCardGoods, } exportGoods.CardPool = uint32(len(gameCardGoods)) for i, _ := range gameCardGoods { if gameCardGoods[i].Status == GameCardGoodsStatusCustomerHold { exportGoods.PlayerHold += 1 } } if uint32(len(gameCardGoods)) > exportGoods.RentStock+exportGoods.PlayerHold { exportGoods.DelayDeliverGameCard = uint32(len(gameCardGoods)) - exportGoods.RentStock - exportGoods.PlayerHold } goodsData = append(goodsData, *exportGoods) } return goodsData, err } func GoodsStatusStringByStatus(status uint32) string { switch status { case 1: return "库存中" case 2: return "在途" case 3: return "客户持有" case 4: return "调拨中" case 5: return "待收回" case 6: return "已收回" case 7: return "异常锁定" } return "" }