Bläddra i källkod

添加了获取本地购买信息功能

MoYuWang 9 månader sedan
förälder
incheckning
931ed351e4

+ 0 - 1
Classes/IAP/Ctl/IAPProcess.cpp

@@ -119,7 +119,6 @@ void IAPProcess::onProductPurchaseSuccess(const std::string& pid) {
     // 记录用户购买信息
     iap::IAPCtlShop::createWith()->addUserBuyInfo(pid);
     printf("购买%s成功\n", pid.c_str());
-    printf("用户类型为: %d\n", iap::IAPCtlShop::createWith()->getUserBuyType());
     
 //    // 判断当前是否在家装场景,如果在游戏场景,则等待
 //    if (bNeedAcceptNow) {

+ 0 - 53
Classes/IAP/IAPCtlShop.cpp

@@ -105,43 +105,6 @@ void IAPCtlShop::showSlideCardsByCoinsIn(cocos2d::Node* pParent, int stillNeedCo
     IAPCtlShopUI::getInstance()->showSlideCardsByCoinsIn(pParent, stillNeedCoins);
 }
 
-UserBuyType IAPCtlShop::getUserBuyType(){
-    // 如果没有购买记录
-    auto buyInfos = IAPUserData::getInstance()->getBuyInfos();
-    if(buyInfos.size() == 0) return UserBuyType::NoShopping;
-    
-    auto conf = IAPConf::getInstance();
-    vector<GoodsInfo> goodInfos;
-    conf->getAllGoods(goodInfos);
-    
-    // 按照价格排序 , 价格相同按照是否为special商品排序
-    sort(goodInfos.begin(), goodInfos.end(), [](GoodsInfo a,GoodsInfo b){
-        if(a.getCostNumber() != b.getCostNumber()) return a.getCostNumber() < b.getCostNumber();
-        if(a.style == "mostValued")return true;
-        if(b.style == "mostValued")return false;
-        return true;
-    });
-    
-    bool onlySpecial = true;    // 是否仅购买特惠商品
-    bool isBuyExpensive = false;    // 是否购买过最贵商品
-    float maxAmount = _conf->getMaxAmount();
-    for(const auto& buyInfo : buyInfos){
-        
-        for(size_t i = 0; i < goodInfos.size(); i++){
-            if(buyInfo != goodInfos[i].id)continue;
-            if(goodInfos[i].type != "mostValued") onlySpecial = false;
-            if(goodInfos[i].getCostNumber() == maxAmount) isBuyExpensive = true;
-        }
-        
-    }
-    
-    // 购买过最贵商品
-    if(isBuyExpensive)return UserBuyType::LotShopping;
-    // 仅购买Special商品
-    if(onlySpecial)return UserBuyType::LittleShopping;
-    // 正常购物
-    return UserBuyType::NormalShopping;
-}
 
 void IAPCtlShop::addUserBuyInfo(std::string commodityID){
     iap::IAPUserData::getInstance()->addBuyInfo(commodityID);
@@ -168,21 +131,5 @@ void IAPCtlShop::clearUserBuyInfo(){
     iap::IAPUserData::getInstance()->clearBuyInfo();
 }
 
-float IAPCtlShop::getUserBuyMaxAmount(){
-    std::vector<std::string> buyInfoIDs = IAPUserData::getInstance()->getBuyInfos();
-    
-    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

+ 15 - 25
Classes/IAP/IAPCtlShop.hpp

@@ -13,41 +13,32 @@
 #include "IAPDefine.hpp"
 #include "IAPDelegate.hpp"
 
-#include "PBConfigData.hpp"
 
 class IAPConf;
 class IAPCtlShopUI;
+class PBConfigData;
 
 NS_IAP_BEGIN
 
-enum UserBuyType{
-    NoShopping,         // 无购买行为
-    LittleShopping,     // 仅购买特惠
-    NormalShopping,     // 正常消费
-    LotShopping         // 土豪
-};
-
 class IAPCtlShop : public cocos2d::Ref {
 public:
     // 创建一个商店控制器
     static IAPCtlShop* createWith();
-
-    // 初始化
-    // cfgFN 配置文件名
-    void init(std::string& cfgFN);
     
     // 设置代理
     // delegate 代理的实现
     void setDelegate(IAPDelegate* delegate);
 
+    // 初始化普通商店卡片配置
+    // cfgFN 配置文件名
+    void init(std::string& cfgFN);
+    
     // 设置失败时内购卡片的配置
+    // cfgFN 配置文件名
     void setCfg4Failure(std::string& cfgFN);
-
-    // 显示失败时的内购卡片
-    void displayFailureCardIn(cocos2d::Node*, std::vector<std::string> cardsName);
     
     // 设置当前设备的等级
-    // level 等级: 1 表示初级, 2 表示中级, 3 表示高级
+    // level 等级: 1 表示初级, 2 表示中级, 3 表示高级 (中级目前没有设计)
     void setDeviceLevel(int level);
 
     // 添加一个商店版位
@@ -67,31 +58,30 @@ public:
     // 清空活动
     void clearPlacement();
     
-    // 获取活动礼包总数
+    // 获取活动版位总数
     size_t getPlacementCount();
     
-    // 在某个节点中显示
+    // 在某个节点中打开普通商店
     // pParent 父节点
     // requirement 对商店的要求,比如说最低金币数
     void showInNode(cocos2d::Node* pParent, ShopRequirement& requirement);
     
-    // 以滑动卡片的形式在某个节点中显示满足金币条件的所有商店卡片
+    // 显示失败时的内购卡片(失败时卡片,非普通商店卡片)
+    // Node 父节点
+    // cardsName 内购卡片名称
+    void displayFailureCardIn(cocos2d::Node*, std::vector<std::string> cardsName);
+    
+    // 以滑动卡片的形式在某个节点中显示满足金币条件的所有 普通商店卡片(暂未使用)删除?
     // pParent 父节点
     // stillNeedCoins 距离所需要的金币数还差多少金币
     void showSlideCardsByCoinsIn(cocos2d::Node* pParent, int stillNeedCoins);
     
-    // 获取用户类型
-    UserBuyType getUserBuyType();
-    
     // 添加用户购买信息 并 从delegate发送购买的道具信息
     void addUserBuyInfo(std::string commodityID);
     
     // 清除用户购买信息
     void clearUserBuyInfo();
     
-    // 获取用户购买过的最贵礼包金额
-    float getUserBuyMaxAmount();
-    
 private:
     
     

+ 3 - 3
Classes/IAP/Shop/IAPCtlShopUI.cpp

@@ -222,8 +222,8 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll, iap::ShopRequirement& requir
     // 获取版位信息
     int bigPackCount,smallPackCount; // 需要显示的礼包
     auto iapCtlShop = iap::IAPCtlShop::createWith();
-    auto userBuyType = iapCtlShop->getUserBuyType();
-    int leval = IAPRunTimeData::getInstance()->getDeviceLevel();    //获取设备等级
+    auto userBuyType = iap::IAPRunTimeData::getInstance()->getUserBuyType();
+    int leval = iap::IAPRunTimeData::getInstance()->getDeviceLevel();    //获取设备等级
     size_t placementCount = iapCtlShop->getPlacementCount();    // 获取活动礼包数量
     switch(leval){
         case 1:
@@ -316,7 +316,7 @@ void IAPCtlShopUI::constructShopItem(bool bShowAll, iap::ShopRequirement& requir
     if(userBuyType == iap::UserBuyType::NormalShopping && !bShowAll){
         // (当前已按 大礼包 > 小礼包,金额小 > 金额大 的优先级排序)
         // 获取购买过的最大金额
-        float maxn = iapCtlShop->getUserBuyMaxAmount();
+        float maxn = iap::IAPRunTimeData::getInstance()->getUserBuyMaxAmount();
         // 构建大礼包
         if(bigPackCount == 2){
             // 查找购买过的最高金额更高一级对应的常规礼包

+ 64 - 0
Classes/IAP/User/IAPRunTimeData.cpp

@@ -6,6 +6,12 @@
 //
 
 #include "IAPRunTimeData.hpp"
+#include "IAPUserData.hpp"
+#include "IAPConf.hpp"
+
+#include "cocos2d.h"
+
+NS_IAP_BEGIN
 
 IAPRunTimeData* IAPRunTimeData::_instance = nullptr;
 
@@ -33,3 +39,61 @@ int IAPRunTimeData::getDeviceLevel(){
 void IAPRunTimeData::_init(){
     _leval = 1;
 }
+
+float IAPRunTimeData::getUserBuyMaxAmount(){
+    auto conf = IAPConf::getInstance();
+    std::vector<std::string> buyInfoIDs = IAPUserData::getInstance()->getBuyInfos();
+    
+    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;
+}
+
+UserBuyType IAPRunTimeData::getUserBuyType(){
+    auto conf = IAPConf::getInstance();
+    // 如果没有购买记录
+    auto buyInfos = IAPUserData::getInstance()->getBuyInfos();
+    if(buyInfos.size() == 0) return UserBuyType::NoShopping;
+    
+    vector<GoodsInfo> goodInfos;
+    conf->getAllGoods(goodInfos);
+    
+    // 按照价格排序 , 价格相同按照是否为special商品排序
+    sort(goodInfos.begin(), goodInfos.end(), [](GoodsInfo a,GoodsInfo b){
+        if(a.getCostNumber() != b.getCostNumber()) return a.getCostNumber() < b.getCostNumber();
+        if(a.style == "mostValued")return true;
+        if(b.style == "mostValued")return false;
+        return true;
+    });
+    
+    bool onlySpecial = true;    // 是否仅购买特惠商品
+    bool isBuyExpensive = false;    // 是否购买过最贵商品
+    float maxAmount = conf->getMaxAmount();
+    for(const auto& buyInfo : buyInfos){
+        
+        for(size_t i = 0; i < goodInfos.size(); i++){
+            if(buyInfo != goodInfos[i].id)continue;
+            if(goodInfos[i].type != "mostValued") onlySpecial = false;
+            if(goodInfos[i].getCostNumber() == maxAmount) isBuyExpensive = true;
+        }
+        
+    }
+    
+    // 购买过最贵商品
+    if(isBuyExpensive)return UserBuyType::LotShopping;
+    // 仅购买Special商品
+    if(onlySpecial)return UserBuyType::LittleShopping;
+    // 正常购物
+    return UserBuyType::NormalShopping;
+}
+
+NS_IAP_END

+ 19 - 0
Classes/IAP/User/IAPRunTimeData.hpp

@@ -10,6 +10,18 @@
 
 #include <stdio.h>
 
+#include "IAPDefine.hpp"
+
+NS_IAP_BEGIN
+
+enum UserBuyType{
+    NoShopping,         // 无购买行为
+    LittleShopping,     // 仅购买特惠
+    NormalShopping,     // 正常消费
+    LotShopping         // 土豪
+};
+
+
 class IAPRunTimeData{
 public:
     static IAPRunTimeData* getInstance();
@@ -19,6 +31,11 @@ public:
     
     int getDeviceLevel();
     
+    // 获取用户类型
+    UserBuyType getUserBuyType();
+    
+    // 获取用户购买过的最贵礼包金额
+    float getUserBuyMaxAmount();
 private:
     void _init();
     
@@ -27,4 +44,6 @@ private:
     int _leval;
 };
 
+NS_IAP_END
+
 #endif /* IAPRunTimeData_hpp */

+ 42 - 2
Classes/IAP/User/IAPUserData.cpp

@@ -23,14 +23,17 @@ IAPUserData::IAPUserData(){
     init();
 }
 
+IAPUserData::~IAPUserData() {
+    saveVectorString(_buyInfos, "buyInfos");
+}
+
 void IAPUserData::init(){
     // 提取用户本地购买信息
-    
+    _buyInfos = loadVectorString("buyInfos");
 }
 
 void IAPUserData::addBuyInfo(std::string commodityID){
     _buyInfos.push_back(commodityID);
-    
 }
 
 void IAPUserData::addBuyInfo(std::vector<std::string> commodityIDs){
@@ -47,4 +50,41 @@ void IAPUserData::clearBuyInfo(){
     _buyInfos.clear();
 }
 
+// 序列化 vector<string> 为单个字符串
+std::string IAPUserData::serialize(const std::vector<std::string>& vec) {
+    std::ostringstream oss;
+    for (size_t i = 0; i < vec.size(); ++i) {
+        if (i != 0) oss << ",";  // 使用逗号作为分隔符
+        oss << vec[i];
+    }
+    return oss.str();
+}
+
+// 反序列化单个字符串为 vector<string>
+std::vector<std::string> IAPUserData::deserialize(const std::string& str) {
+    std::vector<std::string> vec;
+    std::istringstream iss(str);
+    std::string item;
+    while (std::getline(iss, item, ',')) {  // 以逗号为分隔符
+        vec.push_back(item);
+    }
+    return vec;
+}
+
+// 保存 vector<string>
+void IAPUserData::saveVectorString(const std::vector<std::string>& vec, const std::string& key) {
+    auto userDefault = cocos2d::UserDefault::getInstance();
+    std::string serializedData = serialize(vec);
+    userDefault->setStringForKey(key.c_str(), serializedData);
+    userDefault->flush();
+}
+
+// 读取 vector<string>
+std::vector<std::string> IAPUserData::loadVectorString(const std::string& key) {
+    auto userDefault = cocos2d::UserDefault::getInstance();
+    std::string serializedData = userDefault->getStringForKey(key.c_str(), "");
+    return deserialize(serializedData);
+}
+
+
 NS_IAP_END

+ 6 - 0
Classes/IAP/User/IAPUserData.hpp

@@ -19,6 +19,7 @@ public:
     static IAPUserData* getInstance();
     
     IAPUserData();
+    ~IAPUserData();
     
     // 添加购买信息
     // 参数说明 : 商品id
@@ -35,6 +36,11 @@ private:
     
     void init();
     
+    std::string serialize(const std::vector<std::string>& vec);
+    std::vector<std::string> deserialize(const std::string& str);
+    void saveVectorString(const std::vector<std::string>& vec, const std::string& key);
+    std::vector<std::string> loadVectorString(const std::string& key);
+    
 private:
     static IAPUserData* _instance;