123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- //
- // IAPCtlShopUI.cpp
- // TileManor
- //
- // Created by 徐炼新 on 2024/1/16.
- //
- #include "IAPCtlShopUI.hpp"
- #include "IAPCtlShopItem.hpp"
- #include "RUUtils.h"
- #include "RUPlatform.h"
- #include "IAPCtlShop.hpp"
- #include "IAPUserData.hpp"
- #include <regex>
- IAPCtlShopUI* IAPCtlShopUI::_instance = nullptr;
- IAPCtlShopUI* IAPCtlShopUI::getInstance() {
- if (_instance == nullptr) {
- _instance = new IAPCtlShopUI();
- _instance->autorelease();
- _instance->retain();
- }
- return _instance;
- }
- IAPCtlShopUI::IAPCtlShopUI() {
- }
- IAPCtlShopUI::~IAPCtlShopUI() {
-
- }
- bool IAPCtlShopUI::isShowing() {
- return _bUIShowing;
- }
- void IAPCtlShopUI::clear() {
- _goodsInfo.clear();
- for (auto& gi : _goodsItems) {
- gi->release();
- }
- _goodsItems.clear();
- _allSizes.clear();
- _cb = nullptr;
- }
- bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, 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);
- }
-
- // 构建 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;
- }
- 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);
- }
- // 过滤掉不符合的金币
- filterGoods(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;
- } else if (data.notify == "绑定coin节点") {
- // _igCoin = new MapIGCoin(data.reboltRedManager);
- } else if (data.notify == "退出") {
- auto rm = RemoveSelf::create();
- auto cf = CallFunc::create([=]() {
- _layer->removeFromParent();
- _layer = nullptr;
- _bUIShowing = false;
- redutils::Platform::getInstance()->reportLog("iap closed");
- });
- _layer->runAction(Sequence::create(rm, cf, NULL));
- if (_cb) {
- _cb();
- }
- _cb = nullptr;
- }
- }
- void IAPCtlShopUI::constructShopItem(bool bShowAll) {
- int index = 0;
- _tableData.setCascadeOpacity(true);
- _tableData.clear();
- cocos2d::Size size = _ndScrollArea->getContentSize();
- auto delayIdx = 0;
- cocos2d::Vec2 offset(size.width, 0);
- float dur = 0.4;
- int height = 0;
-
- // 加入一个表头
- {
- Node* nd = Node::create();
- _tableData.insertCell(index++, nd);
- int h = size.height*0.08;
- _allSizes.push_back(cocos2d::Size(size.width, h));
- height += h;
- }
-
- // 重新获取
- if(bShowAll)IAPConf::getInstance()->getAllGoods(_goodsInfo);
- // 根据用户类型进行礼包排序
- switch (iap::IAPUserData::getInstance()->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;
- }
- // 当前有效的区域
- int bigPackCount,SmallPackCount; // 需要显示的礼包
- auto iapCtlShop = iap::IAPCtlShop::createWith();
- int leval = iapCtlShop->getDeviceLevel();
- size_t placementCount = iapCtlShop->getPlacementCount();
- switch(leval){
- case 1:
- // 低等级
- bigPackCount = 2;
- SmallPackCount = 1;
- break;
- case 2:
- // 中等级
- break;
- case 3:
- if(placementCount >= 2){
- bigPackCount = 3;
- SmallPackCount = 0;
- }else{
- bigPackCount = 2;
- SmallPackCount = 2;
- }
- // 高等级
- break;
- default:
- break;
- }
-
- // 显示商品
- 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, 这个是一定会有动画的
- auto sz = cocos2d::Size(584, 130);
- Node* nd = Node::create();
- nd->setCascadeOpacityEnabled(true);
- nd->setCascadeColorEnabled(true);
- _btnShowAll = redutils::RUReboltLayer::createReboltLayer("shop_more_btn.redream");
- nd->addChild(_btnShowAll);
- _btnShowAll->setPosition(Vec2(size.width/2.0, sz.height/2.0) + offset);
- _tableData.insertCell(index++, nd);
- _btnShowAll->registerOnNotify([this](const redutils::ReboltNotifyData& data){
- if (data.notify == "点击") {
- auto rm = RemoveSelf::create();
- auto cf = CallFunc::create([=](){
- _btnShowAll = NULL;
- _tableData.clear();
- _goodsItems.clear();
- _allSizes.clear();
- constructShopItem(true);
- _tableView->reloadData(true);
- });
- _btnShowAll->runAction(Sequence::create(rm, cf, NULL));
- }
- });
- redutils::iterateNode(nd, [](Node* nd){
- nd->setCascadeOpacityEnabled(true);
- nd->setCascadeColorEnabled(true);
- });
- _btnShowAll->runBehaviacWhitFunName("初始化");
- _allSizes.push_back(sz);
-
- // 加入动画
- auto d = DelayTime::create(delayIdx*dur/8.0);
- auto m = EaseBackOut::create(MoveBy::create(dur, cocos2d::Vec2(-offset.x, offset.y)));
- _btnShowAll->runAction(Sequence::create(d, m, NULL));
- delayIdx ++;
- } else {
- // 底部添加一个额外节点(一个是底部的广告,还有就是美观一些)
- _tableData.insertCell(index++, Node::create());
- _allSizes.push_back(cocos2d::Size(584, 150));
- }
-
- _tableData._numberOfCellsInTableView = [=](cocos2d::extension::TableViewSmooth*)->ssize_t{
- return _allSizes.size();
- };
- _tableData._tableCellSizeForIndex = [=](cocos2d::extension::TableViewSmooth*, ssize_t idx)->Size{
- if (idx < _allSizes.size()) {
- return _allSizes[idx];
- } else {
- return Size(0,0);
- }
- };
-
- // 防止拉动的时候才创建
- _layer->scheduleOnce([=](float){
- for (int i=0; i<_allSizes.size(); i++) {
- _tableView->updateCellAtIndex(i);
- }
- }, 0.05, "SCH_Update_Cells");
- }
- void IAPCtlShopUI::filterGoods(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::sortGoods(bool flag){
-
- sort(_goodsInfo.begin(), _goodsInfo.end(), [flag](GoodsInfo a, GoodsInfo b){
- if(a.type != b.type){
- if(a.type == "panel"){
- return true;
- }else if(b.type == "panel"){
- return false;
- }
- }
- float val_a,val_b;
-
- std::regex re(R"(\d+(\.\d{1,2})?)"); // 匹配整数或最多两位小数的数字
- std::smatch match;
-
- if (std::regex_search(a.cost, match, re)) {
- val_a = stof(match[0]); // 提取价格
- } else {
- log("IAPUserData::getUserBuyType : 转换失败");
- }
-
- if (std::regex_search(b.cost, match, re)) {
- val_b = stof(match[0]); // 提取价格
- } else {
- log("IAPUserData::getUserBuyType : 转换失败");
- }
-
- if(flag) return val_a < val_b;
- else return val_a > val_b;
- });
-
- }
- void IAPCtlShopUI::quit() {
- if (_layer) {
- _layer->runBehaviacWhitFunName("退出");
- }
- }
|