package items import ( "fmt" "go_dreamfactory/lego/core" "go_dreamfactory/modules" "go_dreamfactory/pb" cfg "go_dreamfactory/sys/configure/structs" "time" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/x/bsonx" ) ///背包缓存数据管理组件 type ModelItemsComp struct { modules.MCompModel module *Items } //组件初始化接口 func (this *ModelItemsComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, opt core.IModuleOptions) (err error) { this.MCompModel.Init(service, module, comp, opt) this.module = module.(*Items) this.TableName = "items" //创建uid索引 this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{ Keys: bsonx.Doc{{Key: "uid", Value: bsonx.Int32(1)}}, }) return } ///查询用户背包数据 func (this *ModelItemsComp) QueryUserPack(uId string) (itmes []*pb.DB_UserItemData, err error) { itmes = make([]*pb.DB_UserItemData, 0) if err = this.GetList(uId, &itmes); err != nil { this.module.Errorf("err:%v", err) } return } ///查询用户指定格子的物品数据 func (this *ModelItemsComp) QueryUserPackByGridId(uId string, grid string) (itme *pb.DB_UserItemData, err error) { itme = &pb.DB_UserItemData{} if err = this.GetListObj(uId, grid, itme); err != nil { this.module.Errorf("err:%v", err) } return } //更新用户的背包信息 func (this *ModelItemsComp) AddUserPack(uId string, itmes ...*pb.DB_UserItemData) (err error) { for _, v := range itmes { this.AddList(uId, v.GridId, v) } return } //更新用户的背包信息 func (this *ModelItemsComp) UpdateUserPack(uid string, itmes ...*pb.DB_UserItemData) (err error) { for _, v := range itmes { this.ChangeList(uid, v.GridId, map[string]interface{}{ "amount": v.Amount, "isNewItem": v.IsNewItem, "lastopt": time.Now().Unix(), }) } return } //更新用户的背包信息 func (this *ModelItemsComp) DeleteUserPack(uId string, itmes ...*pb.DB_UserItemData) (err error) { gridIds := make([]string, len(itmes)) for i, v := range itmes { gridIds[i] = v.GridId } if err = this.DelListlds(uId, gridIds...); err != nil { this.module.Errorf("err:%v", err) return } return } //查询用户背包物品数量 func (this *ModelItemsComp) QueryUserPackItemsAmount(uId string, itemid ...string) (result map[string]uint32) { var ( itmes []*pb.DB_UserItemData err error ) if itmes, err = this.QueryUserPack(uId); err != nil { this.module.Errorf("err:%v", err) return } result = map[string]uint32{} for _, v := range itmes { for _, v1 := range itemid { if v.ItemId == v1 { result[v1] += v.Amount } } } return } ///添加或则减少物品到用户背包 func (this *ModelItemsComp) AddItemToUserPack(uId string, itemId string, addnum int32) (change []*pb.DB_UserItemData, err error) { var ( itmes []*pb.DB_UserItemData add []*pb.DB_UserItemData del []*pb.DB_UserItemData update []*pb.DB_UserItemData leftnum int64 ) if addnum == 0 { return } if itmes, err = this.QueryUserPack(uId); err != nil { this.module.Errorf("err:%v", err) return } change = make([]*pb.DB_UserItemData, 0) add, update, del, leftnum = this.addItemToUserPack(uId, itmes, itemId, addnum) if leftnum < 0 { err = ItemNotEnoughError return } else if leftnum > 0 { err = PackGridNumUpper return } if len(add) > 0 { if err = this.AddUserPack(uId, add...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, add...) } if len(del) > 0 { if err = this.DeleteUserPack(uId, del...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, del...) } if len(update) > 0 { if err = this.UpdateUserPack(uId, update...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, update...) } return } ///添加或则减少多个物品到用户背包 func (this *ModelItemsComp) AddItemsToUserPack(uId string, items map[string]int32) (change []*pb.DB_UserItemData, err error) { var ( itmes []*pb.DB_UserItemData add []*pb.DB_UserItemData del []*pb.DB_UserItemData update []*pb.DB_UserItemData leftnum int64 ) if itmes, err = this.QueryUserPack(uId); err != nil { this.module.Errorf("err:%v", err) return } change = make([]*pb.DB_UserItemData, 0) for k, v := range items { add, update, del, leftnum = this.addItemToUserPack(uId, itmes, k, v) if leftnum < 0 { err = ItemNotEnoughError return } else if leftnum > 0 { err = PackGridNumUpper return } if len(add) > 0 { if err = this.AddUserPack(uId, add...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, add...) } if len(del) > 0 { if err = this.DeleteUserPack(uId, del...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, del...) } if len(update) > 0 { if err = this.UpdateUserPack(uId, update...); err != nil { this.module.Errorf("err:%v", err) return } change = append(change, update...) } } return } ///修改指定格子的物品数量 func (this *ModelItemsComp) AddItemToUserPackByGrid(uId string, gridid string, addnum int32) (change []*pb.DB_UserItemData, err error) { var ( conf *cfg.Game_itemData itme *pb.DB_UserItemData num int64 amount int64 ) if addnum == 0 { return } if itme, err = this.QueryUserPackByGridId(uId, gridid); err != nil { this.module.Errorf("err:%v", err) return } if conf, err = this.module.configure.GetItemConfigure(itme.ItemId); err != nil { this.module.Errorf("err:%v", err) return } amount = int64(itme.Amount) num = amount + int64(addnum) change = make([]*pb.DB_UserItemData, 0) if num < 0 { err = ItemNotEnoughError } else { if conf.UpperLimit > 0 && num > int64(conf.UpperLimit) { err = GirdAmountUpper return } else { itme.Amount = uint32(num) if itme.Amount > 0 { this.UpdateUserPack(uId, itme) } else { this.DeleteUserPack(uId, itme) } change = append(change, itme) } } return } ///添加移除物品到用户背包 func (this *ModelItemsComp) addItemToUserPack(uid string, items []*pb.DB_UserItemData, itemId string, addnum int32) (add, update, del []*pb.DB_UserItemData, leftnum int64) { var ( err error conf *cfg.Game_itemData num int64 isNew bool ) if addnum == 0 { return } if conf, err = this.module.configure.GetItemConfigure(itemId); err != nil { this.module.Errorln(err) return } if conf.UpperLimit == 0 { err = fmt.Errorf("item UpperLimit is 0") return } isNew = true leftnum = int64(addnum) add = make([]*pb.DB_UserItemData, 0) del = make([]*pb.DB_UserItemData, 0) update = make([]*pb.DB_UserItemData, 0) for _, v := range items { if v.ItemId == itemId { isNew = false num = int64(v.Amount) + int64(leftnum) if num < 0 { leftnum += int64(v.Amount) v.Amount = 0 del = append(del, v) } else if num > 0 && num < int64(v.Amount) { leftnum = 0 v.Amount = uint32(num) update = append(update, v) break } else if num > 0 && num > int64(v.Amount) { if conf.UpperLimit > 0 { if num <= int64(conf.UpperLimit) { leftnum = 0 v.Amount = uint32(num) update = append(update, v) break } else { if v.Amount < uint32(conf.UpperLimit) { leftnum = int64(num - int64(conf.UpperLimit)) v.Amount = uint32(conf.UpperLimit) update = append(update, v) } } } else { leftnum = 0 v.Amount = uint32(num) update = append(update, v) } } else if num == 0 { leftnum = 0 v.Amount = 0 del = append(del, v) } } } if leftnum < 0 { //背包物品不够 return } if leftnum > 0 { //还没有放完 寻找空的格子填充 index := int32(len(items)) for leftnum > 0 { //需要补充格子 if conf.UpperLimit < 0 || (conf.UpperLimit > 0 && leftnum <= int64(conf.UpperLimit)) { grid := &pb.DB_UserItemData{ GridId: primitive.NewObjectID().Hex(), UId: uid, ItemId: itemId, Amount: uint32(leftnum), CTime: time.Now().Unix(), IsNewItem: isNew, } if conf.Time > 0 { grid.ETime = time.Now().Add(time.Minute * time.Duration(conf.Time)).Unix() } items = append(items, grid) add = append(add, grid) leftnum = 0 break } else { leftnum -= int64(conf.UpperLimit) grid := &pb.DB_UserItemData{ GridId: primitive.NewObjectID().Hex(), UId: uid, ItemId: itemId, Amount: uint32(conf.UpperLimit), CTime: time.Now().Unix(), IsNewItem: isNew, } if conf.Time > 0 { grid.ETime = time.Now().Add(time.Minute * time.Duration(conf.Time)).Unix() } items = append(items, grid) add = append(add, grid) index++ } if index > GridMaxNUm { //格子已达上限 break } } } return }