Browse Source

修改了进入商店时正常消费用户显示礼包的算法

MoYuWang 9 months ago
parent
commit
2274338cd6

+ 31 - 0
Classes/IAP/Conf/IAPConf.cpp

@@ -73,3 +73,34 @@ void IAPConf::getAllGoods(std::vector<GoodsInfo>& goods) {
         goods.push_back(gi);
     }
 }
+
+float IAPConf::getMaxAmount(){
+    if(_bc == nullptr) return 0;
+    float maxn = 0.0;
+    
+    vector<GoodsInfo> goodInfos;
+    getAllGoods(goodInfos);
+    
+    for(const auto& goodInfo : goodInfos){
+        maxn = std::max(maxn, goodInfo.getCostNumber());
+    }
+    
+    return maxn;
+}
+
+float IAPConf::getCoinNum(std::string id){
+    if(_bc == nullptr) return -1;
+    float num = -1;
+    int cnt = atoi(_bc->getConf("goods", "count").c_str());
+    for (int i=1; i<=cnt; i++) {
+        GoodsInfo gi;
+        std::string key = "goods_" + Value(i).asString();
+        gi.id = _bc->getConf("goods", key+":id");
+        if(gi.id == id){
+            gi.cost = _bc->getConf("goods", key+":cost");
+            num = gi.getCostNumber();
+            break;
+        }
+    }
+    return num;
+}

+ 4 - 0
Classes/IAP/Conf/IAPConf.hpp

@@ -114,6 +114,10 @@ public:
     
     void getAllGoods(std::vector<GoodsInfo>&);
     
+    float getMaxAmount();
+    
+    float getCoinNum(std::string id);
+    
 private:
     IAPConf() = default;
     

+ 13 - 12
Classes/IAP/IAPCtlShop.cpp

@@ -106,7 +106,7 @@ UserBuyType IAPCtlShop::getUserBuyType(){
     
     bool onlySpecial = true;    // 是否仅购买特惠商品
     bool isBuyExpensive = false;    // 是否购买过最贵商品
-    float maxAmount = getMaxAmount();
+    float maxAmount = _conf->getMaxAmount();
     for(const auto& buyInfo : buyInfos){
         
         for(size_t i = 0; i < goodInfos.size(); i++){
@@ -136,20 +136,21 @@ void IAPCtlShop::clearUserBuyInfo(){
     iap::IAPUserData::getInstance()->clearBuyInfo();
 }
 
-
-float IAPCtlShop::getMaxAmount(){
-    float maxn = 0.0;
-    
-    auto conf = IAPConf::getInstance();
-    vector<GoodsInfo> goodInfos;
-    conf->getAllGoods(goodInfos);
+float IAPCtlShop::getUserBuyMaxAmount(){
+    std::vector<std::string> buyInfoIDs = IAPUserData::getInstance()->getBuyInfos();
     
-    for(const auto& goodInfo : goodInfos){
-        maxn = std::max(maxn, goodInfo.getCostNumber());
+    std::set<std::string> buyInfoID;
+    // 去重
+    for(const auto& info : buyInfoIDs){
+        buyInfoID.insert(info);
+    }
+    // 提取最大金额
+    float maxn = -1;
+    for(const auto& id : buyInfoID){
+        float coinNum = _conf->getCoinNum(id);
+        maxn = maxn > coinNum ? maxn : coinNum;
     }
-    
     return maxn;
 }
 
-
 NS_IAP_END

+ 4 - 2
Classes/IAP/IAPCtlShop.hpp

@@ -82,9 +82,11 @@ public:
     // 清除用户购买信息
     void clearUserBuyInfo();
     
+    // 获取用户购买过的最贵礼包金额
+    float getUserBuyMaxAmount();
+    
 private:
-    // 获取用户购买信息中最贵的金额
-    float getMaxAmount();
+    
     
 private:
     static IAPCtlShop* _instance;

+ 213 - 50
Classes/IAP/Shop/IAPCtlShopUI.cpp

@@ -81,11 +81,9 @@ bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, iap::ShopRequirement& requi
     if (_goodsInfo.size() == 0) {
         IAPConf::getInstance()->getAllGoods(_goodsInfo);
     }
-    // 过滤掉不符合的金币
-    filterGoods(requirement);
     
     // 构建 list 区域
-    constructShopItem(false);
+    constructShopItem(false, requirement);
     cocos2d::Size size = _ndScrollArea->getContentSize();
     _tableView = redutils::RUTableView::create(&_tableData, cocos2d::Size(size.width, size.height));
     _tableView->setCascadeOpacityEnabled(true);
@@ -230,7 +228,7 @@ void IAPCtlShopUI::_onNotifyDevelopment(const redutils::ReboltNotifyData& data)
     }
 }
 
-void IAPCtlShopUI::constructShopItem(bool bShowAll) {
+void IAPCtlShopUI::constructShopItem(bool bShowAll, iap::ShopRequirement& requirement) {
     int index = 0;
     _tableData.setCascadeOpacity(true);
     _tableData.clear();
@@ -248,31 +246,15 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
         _allSizes.push_back(cocos2d::Size(size.width, h));
         height += h;
     }
-    
-    // 重新获取
-    if(bShowAll)IAPConf::getInstance()->getAllGoods(_goodsInfo);
-    // 根据用户类型进行礼包排序
-    switch (iap::IAPCtlShop::createWith()->getUserBuyType()) {
-        case iap::UserBuyType::NoShopping:
-            sortGoods(true);
-            break;
-        case iap::UserBuyType::LittleShopping:
-            sortGoods(true);
-            break;
-        case iap::UserBuyType::NormalShopping:
-            sortGoods(true);
-            break;
-        case iap::UserBuyType::LotShopping:
-            sortGoods(false);
-            break;
-        default:
-            break;
-    }
-    // 当前有效的区域
+    // 开始构建
+    // 获取礼包信息
+    IAPConf::getInstance()->getAllGoods(_goodsInfo);
+    // 获取版位信息
     int bigPackCount,smallPackCount; // 需要显示的礼包
     auto iapCtlShop = iap::IAPCtlShop::createWith();
-    int leval = IAPRunTimeData::getInstance()->getDeviceLevel();
-    size_t placementCount = iapCtlShop->getPlacementCount();
+    auto userBuyType = iapCtlShop->getUserBuyType();
+    int leval = IAPRunTimeData::getInstance()->getDeviceLevel();    //获取设备等级
+    size_t placementCount = iapCtlShop->getPlacementCount();    // 获取活动礼包数量
     switch(leval){
         case 1:
             // 低等级
@@ -295,10 +277,8 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
         default:
             break;
     }
-    
-    // 展示活动版位
+    // 展示活动礼包
     if(_placements.size() != 0){
-        // 展示活动版位中的活动
         for(const auto& placement : _placements){
             bool isShow = false;
             if(bShowAll){
@@ -340,31 +320,89 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
             
         }
     }
-    // 判断是否还有版位
-    if(bigPackCount != 0 || smallPackCount != 0 || bShowAll){
-        // 显示常规商品
-        for (const auto& gi : _goodsInfo) {
-            // 判断是否显示
-            bool isShow = false;
-            if (bShowAll) {
-                isShow = true;
-            }else{
-                if(gi.type == "panel" && bigPackCount > 0){
-                    isShow = true;
-                    bigPackCount--;
+    // 根据用户类型进行礼包排序
+    switch (userBuyType) {
+        case iap::UserBuyType::NoShopping:
+            sortGoods(true);
+            break;
+        case iap::UserBuyType::LittleShopping:
+            sortGoods(true);
+            break;
+        case iap::UserBuyType::NormalShopping:
+            sortGoods(true);
+            break;
+        case iap::UserBuyType::LotShopping:
+            sortGoods(false);
+            break;
+        default:
+            break;
+    }
+    // 判断是否展示全部
+    if(!bShowAll){
+        // 不展示全部,过滤掉不合格的礼包
+        filterGoods(requirement);
+    }
+    // 判断是否为正常消费
+    if(userBuyType == iap::UserBuyType::NormalShopping && !bShowAll){
+        // (当前已按 大礼包 > 小礼包,金额小 > 金额大 的优先级排序)
+        // 获取购买过的最大金额
+        float maxn = iapCtlShop->getUserBuyMaxAmount();
+        // 构建大礼包
+        if(bigPackCount == 2){
+            // 查找购买过的最高金额更高一级对应的常规礼包
+            int nowAmount = INT_MAX;
+            int nowIndex = -1;
+            for(int i = 0; i < _goodsInfo.size(); i++){
+                if(_goodsInfo[i].type != "panel")continue;
+                if(_goodsInfo[i].getCostNumber() <= maxn)continue;
+                if(nowAmount > _goodsInfo[i].getCostNumber()){
+                    nowAmount = _goodsInfo[i].getCostNumber();
+                    nowIndex = i;
                 }
-                if(gi.type == "bar" && smallPackCount > 0){
-                    isShow = true;
-                    smallPackCount--;
+            }
+            if(nowIndex != -1){
+                bool bNeedAnim = height <= size.height;
+                Node* nd = Node::create();
+                nd->setCascadeOpacityEnabled(true);
+                nd->setCascadeColorEnabled(true);
+                auto si = IAPCtlShopItem::create(_goodsInfo[nowIndex], _placementId);
+                auto sz = si->getSize();
+                cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
+                nd->addChild(si);
+                si->setPosition(bNeedAnim ? pos+offset : pos);
+                _goodsItems.push_back(si);
+                _tableData.insertCell(index++, nd);
+                _allSizes.push_back(sz);
+                height += sz.height;
+                
+                if (bNeedAnim) {
+                    // 加入动画
+                    auto d = DelayTime::create(delayIdx*dur/8.0);
+                    auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
+                    si->runAction(Sequence::create(d, m, NULL));
+                    delayIdx ++;
                 }
             }
-            // 商品显示
-            if (isShow) {
+            bigPackCount--;
+        }
+        if(bigPackCount == 1){
+            // 查找购买过最高金额所对应的常规礼包
+            int nowAmount = INT_MIN;
+            int nowIndex = -1;
+            for(int i = 0; i < _goodsInfo.size(); i++){
+                if(_goodsInfo[i].type != "panel")continue;
+                if(_goodsInfo[i].getCostNumber() > maxn)continue;
+                if(nowAmount <= _goodsInfo[i].getCostNumber()){
+                    nowAmount = _goodsInfo[i].getCostNumber();
+                    nowIndex = i;
+                }
+            }
+            if(nowIndex != -1){
                 bool bNeedAnim = height <= size.height;
                 Node* nd = Node::create();
                 nd->setCascadeOpacityEnabled(true);
                 nd->setCascadeColorEnabled(true);
-                auto si = IAPCtlShopItem::create(gi, _placementId);
+                auto si = IAPCtlShopItem::create(_goodsInfo[nowIndex], _placementId);
                 auto sz = si->getSize();
                 cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
                 nd->addChild(si);
@@ -382,9 +420,130 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
                     delayIdx ++;
                 }
             }
+            bigPackCount--;
+        }
+        // 构建小礼包
+        if(smallPackCount == 2){
+            // 查找购买过的最高金额更高一级对应的金币礼包
+            int nowAmount = INT_MAX;
+            int nowIndex = -1;
+            for(int i = 0; i < _goodsInfo.size(); i++){
+                if(_goodsInfo[i].type != "bar")continue;
+                if(_goodsInfo[i].getCostNumber() <= maxn)continue;
+                if(nowAmount > _goodsInfo[i].getCostNumber()){
+                    nowAmount = _goodsInfo[i].getCostNumber();
+                    nowIndex = i;
+                }
+            }
+            if(nowIndex != -1){
+                bool bNeedAnim = height <= size.height;
+                Node* nd = Node::create();
+                nd->setCascadeOpacityEnabled(true);
+                nd->setCascadeColorEnabled(true);
+                auto si = IAPCtlShopItem::create(_goodsInfo[nowIndex], _placementId);
+                auto sz = si->getSize();
+                cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
+                nd->addChild(si);
+                si->setPosition(bNeedAnim ? pos+offset : pos);
+                _goodsItems.push_back(si);
+                _tableData.insertCell(index++, nd);
+                _allSizes.push_back(sz);
+                height += sz.height;
+                
+                if (bNeedAnim) {
+                    // 加入动画
+                    auto d = DelayTime::create(delayIdx*dur/8.0);
+                    auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
+                    si->runAction(Sequence::create(d, m, NULL));
+                    delayIdx ++;
+                }
+            }
+            smallPackCount--;
+        }
+        if(smallPackCount == 1){
+            // 查找购买过最高金额所对应的金币礼包
+            int nowAmount = INT_MIN;
+            int nowIndex = -1;
+            for(int i = 0; i < _goodsInfo.size(); i++){
+                if(_goodsInfo[i].type != "bar")continue;
+                if(_goodsInfo[i].getCostNumber() > maxn)continue;
+                if(nowAmount <= _goodsInfo[i].getCostNumber()){
+                    nowAmount = _goodsInfo[i].getCostNumber();
+                    nowIndex = i;
+                }
+            }
+            if(nowIndex != -1){
+                bool bNeedAnim = height <= size.height;
+                Node* nd = Node::create();
+                nd->setCascadeOpacityEnabled(true);
+                nd->setCascadeColorEnabled(true);
+                auto si = IAPCtlShopItem::create(_goodsInfo[nowIndex], _placementId);
+                auto sz = si->getSize();
+                cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
+                nd->addChild(si);
+                si->setPosition(bNeedAnim ? pos+offset : pos);
+                _goodsItems.push_back(si);
+                _tableData.insertCell(index++, nd);
+                _allSizes.push_back(sz);
+                height += sz.height;
+                
+                if (bNeedAnim) {
+                    // 加入动画
+                    auto d = DelayTime::create(delayIdx*dur/8.0);
+                    auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
+                    si->runAction(Sequence::create(d, m, NULL));
+                    delayIdx ++;
+                }
+            }
+            smallPackCount--;
+        }
+        
+    }else{
+        // 判断是否还有版位
+        if(bigPackCount != 0 || smallPackCount != 0 || bShowAll){
+            // 显示常规商品
+            for (const auto& gi : _goodsInfo) {
+                // 判断是否显示
+                bool isShow = false;
+                if (bShowAll) {
+                    isShow = true;
+                }else{
+                    if(gi.type == "panel" && bigPackCount > 0){
+                        isShow = true;
+                        bigPackCount--;
+                    }
+                    if(gi.type == "bar" && smallPackCount > 0){
+                        isShow = true;
+                        smallPackCount--;
+                    }
+                }
+                // 商品显示
+                if (isShow) {
+                    bool bNeedAnim = height <= size.height;
+                    Node* nd = Node::create();
+                    nd->setCascadeOpacityEnabled(true);
+                    nd->setCascadeColorEnabled(true);
+                    auto si = IAPCtlShopItem::create(gi, _placementId);
+                    auto sz = si->getSize();
+                    cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
+                    nd->addChild(si);
+                    si->setPosition(bNeedAnim ? pos+offset : pos);
+                    _goodsItems.push_back(si);
+                    _tableData.insertCell(index++, nd);
+                    _allSizes.push_back(sz);
+                    height += sz.height;
+                    
+                    if (bNeedAnim) {
+                        // 加入动画
+                        auto d = DelayTime::create(delayIdx*dur/8.0);
+                        auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
+                        si->runAction(Sequence::create(d, m, NULL));
+                        delayIdx ++;
+                    }
+                }
+            }
         }
     }
-    
     // 添加展示所有按钮
     if (!bShowAll) {
         // 加入show All btn, 这个是一定会有动画的
@@ -408,7 +567,11 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
                         _indicators[placement.first].clear();
                     }
                     _allSizes.clear();
-                    constructShopItem(true);
+                    
+                    iap::ShopRequirement req;
+                    req.coinsMin = 0;
+                    constructShopItem(true, req);
+                    
                     _tableView->reloadData(true);
                 });
                 _btnShowAll->runAction(Sequence::create(rm, cf, NULL));

+ 1 - 1
Classes/IAP/Shop/IAPCtlShopUI.hpp

@@ -68,7 +68,7 @@ private:
 
     void _onNotifyDevelopment(const redutils::ReboltNotifyData& data);
     
-    void constructShopItem(bool bShowAll = false);
+    void constructShopItem(bool bShowAll , iap::ShopRequirement& requirement);
     
     Node* createPlacementUI(const iap::IAPPlacement& placement);