Ver código fonte

添加了记录用户购买信息的代码

MoYuWang 10 meses atrás
pai
commit
3d64741793

+ 2 - 2
Classes/IAP/IAPCtlShop.cpp

@@ -4,6 +4,7 @@
 //
 //  Created by 徐炼新 on 2024/9/30.
 //
+#include "cocos2d.h"
 
 #include "IAPCtlShop.hpp"
 #include "IAPCtlShopUI.hpp"
@@ -55,8 +56,7 @@ void IAPCtlShop::removePlacement(const std::string &id){
 
 void IAPCtlShop::showInNode(cocos2d::Node *pParent, ShopRequirement &requirement){
     _shopUI = IAPCtlShopUI::getInstance();
-    _shopUI->create(pParent, _conf, 1);
-    log("需要的最低金币数为:%d", requirement.coinsMin);
+    _shopUI->create(pParent, _conf, requirement,1);
 }
 
 void IAPCtlShop::showPlacementsInNode(cocos2d::Node *pParent, const vector<std::string> &plIds){

+ 1 - 4
Classes/IAP/IAPDelegate.cpp

@@ -6,8 +6,8 @@
 //
 
 #include "IAPDelegate.hpp"
+#include "IAPUserData.hpp"
 
-NS_IAP_BEGIN
 
 IAPDelegate* IAPDelegate::_instance = nullptr;
 
@@ -17,6 +17,3 @@ IAPDelegate* IAPDelegate::getInstance(){
     }
     return _instance;
 }
-
-
-NS_IAP_END

+ 2 - 4
Classes/IAP/IAPDelegate.hpp

@@ -8,9 +8,7 @@
 #ifndef IAPDelegate_hpp
 #define IAPDelegate_hpp
 
-#include "IAPDefine.hpp"
-
-NS_IAP_BEGIN
+#include <cocos2d.h>
 
 class IAPDelegate {
 public:
@@ -19,8 +17,8 @@ public:
 private:
     static IAPDelegate* _instance;
     
+    
 };
 
-NS_IAP_END
 
 #endif /* IAPDelegate_hpp */

+ 6 - 1
Classes/IAP/Shop/IAPCtlShopItem.cpp

@@ -10,8 +10,11 @@
 #include "IAPProcess.hpp"
 #include "IAPCtlShopUI.hpp"
 #include "IAPSucessProcess.hpp"
+#include "IAPDelegate.hpp"
 #include "RUUtils.h"
 
+#include "IAPUserData.hpp"
+
 IAPCtlShopItem* IAPCtlShopItem::create(const GoodsInfo& gi, int placementId) {
     IAPCtlShopItem* csi = new IAPCtlShopItem(gi);
     csi->_placementId = placementId;
@@ -106,7 +109,9 @@ void IAPCtlShopItem::onNotifyDevelopment(const redutils::ReboltNotifyData& data)
 }
 
 void IAPCtlShopItem::accepted() {
-    // 退出购买界面,展示成功界面
+    // 退出购买界面,展示成功界面,记录购买信息
+    iap::IAPUserData::getInstance()->addBuyInfo(_gi.id);
+    auto type = iap::IAPUserData::getInstance()->getUserBuyType();
     IAPCtlShopUI::getInstance()->quit();
 }
 

+ 77 - 0
Classes/IAP/Shop/IAPCtlShopUI.cpp

@@ -79,6 +79,45 @@ bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, int placementId) {
     return true;
 }
 
+bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, iap::ShopRequirement& requirement,int placementId) {
+    redutils::Platform::getInstance()->reportLog("open iap");
+    _cfg = cfg;
+    _bUIShowing = true;
+    _placementId = placementId;
+    clear();
+    
+    _layer = redutils::RUReboltLayer::createReboltLayer("shop_interface.redream");
+    pNode->addChild(_layer, 3);
+    _layer->registerOnNotify([this](const redutils::ReboltNotifyData& data){
+        _onNotifyDevelopment(data);
+    });
+    _layer->runBehaviacWhitFunName("初始化");
+    
+//    _igCoin->doOwnInit();
+    
+    if (_goodsInfo.size() == 0) {
+        IAPConf::getInstance()->getAllGoods(_goodsInfo);
+    }
+    sortGoods(requirement);
+    
+    // 构建 list 区域
+    constructShopItem(false);
+    cocos2d::Size size = _ndScrollArea->getContentSize();
+    _tableView = redutils::RUTableView::create(&_tableData, cocos2d::Size(size.width, size.height));
+    _tableView->setCascadeOpacityEnabled(true);
+    _tableView->setCascadeColorEnabled(true);
+    _tableView->setDirection(ScrollViewSmooth::Direction::VERTICAL);
+    _tableView->setVerticalFillOrder(TableViewSmooth::VerticalFillOrder::TOP_DOWN, false);
+    _tableView->setDelegate(&_tableData);
+    _tableView->setBounceable(true);
+//    _tableView->setOutSightClean(false);
+    _ndScrollArea->addChild(_tableView);
+    
+    return true;
+}
+
+
+
 void IAPCtlShopUI::_onNotifyDevelopment(const redutils::ReboltNotifyData& data) {
     if (data.notify == "绑定显示区域") {
         _ndScrollArea = data.outNode;
@@ -207,6 +246,44 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll) {
     }, 0.05, "SCH_Update_Cells");
 }
 
+void IAPCtlShopUI::sortGoods(iap::ShopRequirement &requirement){
+    std::map<int, bool> m;
+    int cnt = 0;
+    for(const auto& goodsInfo : _goodsInfo){
+        for(const auto area : goodsInfo.areas){
+            bool flag = false;
+            for(int i = 0;i < area.size(); i++){
+                if(area[i].name != "coin")continue;
+                if(std::stoi(area[i].count) >= requirement.coinsMin){
+                    m[cnt] = true;
+                    flag = true;
+                    break;
+                }else{
+                    m[cnt] = false;
+                    flag = true;
+                    break;
+                }
+            }
+            if(flag)break;
+        }
+        cnt++;
+    }
+    std::vector<GoodsInfo> newGoodsInfo;
+    // 添加符合条件的礼包
+    for(int i = 0;i < _goodsInfo.size(); i++){
+        if(m[i]){
+            newGoodsInfo.push_back(_goodsInfo[i]);
+        }
+    }
+    // 添加不符合条件的礼包(不清楚是不是需要显示,暂放到列表末尾)
+    for(int i = 0;i < _goodsInfo.size(); i++){
+        if(!m[i]){
+            newGoodsInfo.push_back(_goodsInfo[i]);
+        }
+    }
+    _goodsInfo = newGoodsInfo;
+}
+
 void IAPCtlShopUI::quit() {
     if (_layer) {
         _layer->runBehaviacWhitFunName("退出");

+ 5 - 0
Classes/IAP/Shop/IAPCtlShopUI.hpp

@@ -13,6 +13,7 @@
 #include "RUReboltLayer.h"
 #include "RUTableView.h"
 #include "IAPConf.hpp"
+#include "IAPDefine.hpp"
 
 class IAPCtlShopItem;
 class MapIGCoin;
@@ -24,6 +25,7 @@ public:
     
     // 在指定节点内创建
     bool create(cocos2d::Node* pParent, IAPConf* cfg, int placementId = 1);
+    bool create(cocos2d::Node* pNode, IAPConf* cfg, iap::ShopRequirement& requirement,int placementId = 1);
     
     // 设置退出时的回调
     void setCBWhileQuit(std::function<void()> cb) { _cb = cb; }
@@ -43,6 +45,9 @@ private:
     void _onNotifyDevelopment(const redutils::ReboltNotifyData& data);
     
     void constructShopItem(bool bShowAll = false);
+    
+    // 根据所需要的金币进行筛选
+    void sortGoods(iap::ShopRequirement& requirement);
 
 private:
     static IAPCtlShopUI* _instance;

+ 83 - 0
Classes/IAP/User/IAPUserData.cpp

@@ -6,3 +6,86 @@
 //
 
 #include "IAPUserData.hpp"
+#include "IAPConf.hpp"
+
+#include <algorithm>
+#include <string>
+#include <regex>
+
+NS_IAP_BEGIN
+
+IAPUserData* IAPUserData::_instance = nullptr;
+
+IAPUserData* IAPUserData::getInstance(){
+    if(!_instance){
+        _instance = new IAPUserData();
+    }
+    return _instance;
+}
+
+void IAPUserData::init(){
+    
+}
+
+void IAPUserData::addBuyInfo(std::string commodityID){
+    buyInfos.push_back(commodityID);
+}
+
+UserBuyType IAPUserData::getUserBuyType(){
+    // 如果没有购买记录
+    if(buyInfos.size() == 0) return UserBuyType::NoShopping;
+    
+    auto conf = IAPConf::getInstance();
+    vector<GoodsInfo> goodInfos;
+    conf->getAllGoods(goodInfos);
+    
+    struct SortVec{
+        std::string id;
+        float price;
+        bool isSpecial;
+    };
+    vector<SortVec> vec;
+    
+    std::regex re(R"(\d+(\.\d{1,2})?)");  // 匹配整数或最多两位小数的数字
+    for(const auto& goodInfo : goodInfos){
+        bool isSpecial = goodInfo.style == "special" ? true : false;
+        std::smatch match;
+        if (std::regex_search(goodInfo.cost, match, re)) {
+            SortVec sv;
+            sv.id = goodInfo.id;
+            sv.price = std::stof(match[0]);    // 提取价格
+            sv.isSpecial = isSpecial;
+            vec.push_back(sv);
+        } else {
+            log("IAPUserData::getUserBuyType : 转换失败");
+        }
+    }
+    // 按照价格排序 , 价格相同按照是否为special商品排序
+    sort(vec.begin(), vec.end(), [](SortVec a,SortVec b){
+        if(std::fabs(a.price - b.price) < 1e-9) return a.price < b.price;
+        if(a.isSpecial)return true;
+        if(b.isSpecial)return false;
+        return true;
+    });
+    
+    bool onlySpecial = true;
+    bool isBuyExpensive = false;
+    for(const auto& buyInfo : buyInfos){
+        
+        for(size_t i = 0; i < vec.size(); i++){
+            if(buyInfo != vec[i].id)continue;
+            if(!vec[i].isSpecial) onlySpecial = false;
+            if(i == vec.size() - 1) isBuyExpensive = true;
+        }
+        
+    }
+    
+    // 购买过最贵商品
+    if(isBuyExpensive)return UserBuyType::LotShopping;
+    // 仅购买Special商品
+    if(onlySpecial)return UserBuyType::LittleShopping;
+    // 正常购物
+    return UserBuyType::NormalShopping;
+}
+
+NS_IAP_END

+ 35 - 1
Classes/IAP/User/IAPUserData.hpp

@@ -8,6 +8,40 @@
 #ifndef IAPUserData_hpp
 #define IAPUserData_hpp
 
-#include <stdio.h>
+#include <cocos2d.h>
+#include "IAPDefine.hpp"
+
+NS_IAP_BEGIN
+
+enum UserBuyType{
+    NoShopping,         // 无购买行为
+    LittleShopping,     // 仅购买特惠
+    NormalShopping,     // 正常消费
+    LotShopping         // 土豪
+};
+
+class IAPUserData {
+public:
+    static IAPUserData* getInstance();
+    
+    void init();
+    
+    // 添加购买信息
+    // 参数说明 : 商品id
+    void addBuyInfo(std::string commodityID);
+    
+    // 获取用户类型
+    UserBuyType getUserBuyType();
+
+private:
+    
+    
+private:
+    static IAPUserData* _instance;
+    
+    std::vector<std::string> buyInfos;    // 用户购买信息
+};
+
+NS_IAP_END
 
 #endif /* IAPUserData_hpp */

+ 5 - 0
Classes/TestScene.cpp

@@ -77,6 +77,11 @@ void TestScene::onNotifyDevelopment(const redutils::ReboltNotifyData& data){
         log("点击设备等级3按钮");
     }else if(data.notify == "点击失败"){
         log("点击失败时金币不够按钮");
+        
+        iap::ShopRequirement shopRequirement;
+        shopRequirement.coinsMin = 10000;
+        
+        _iapShop->showInNode(this, shopRequirement);
     }else if(data.notify == "点击重置"){
         log("重置");
     }