123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614 |
- //
- // IAPCtlShopUI.cpp
- // TileManor
- //
- // Created by 徐炼新 on 2024/1/16.
- //
- #include "IAPCtlShop.hpp"
- #include "ui/UIPageView.h"
- #include "RUUtils.h"
- #include "RUPlatform.h"
- #include "IAPConf.hpp"
- #include "IAPCtlShopUI.hpp"
- #include "IAPCtlShopItem.hpp"
- #include "IAPDefine.hpp"
- #include "IAPCardView.hpp"
- #include "IAPRunTimeData.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();
- _placementItems.clear();
- _failItems.clear();
- for(const auto& placement : _placements){
- _indicators[placement.first].clear();
- }
- _allSizes.clear();
- _cb = nullptr;
- }
- bool IAPCtlShopUI::create(Node* pNode, IAPConf* cfg, iapshop::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);
- }
-
- // 构建 list 区域
- constructShopItem(false, requirement);
- 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::addAPlacement(const iapshop::IAPPlacement &plInfo){
- // 如果该活动ID存在,则添加失败
- if(_placements.count(plInfo.id) != 0)return false;
-
- _placements[plInfo.id] = plInfo;
-
- std::vector<Node*> nodeVec;
- _indicators[plInfo.id] = nodeVec;
-
- return true;
- }
- void IAPCtlShopUI::removePlacement(const std::string &id){
- _placements.erase(id);
-
- _indicators.erase(id);
-
- }
- bool IAPCtlShopUI::addCardToPlacement(const std::string &id, iapshop::IAPCard *card){
- if(_placements.count(id) == 0)return false;
- _placements[id].cards.push_back(card);
- return true;
- }
- bool IAPCtlShopUI::removeCardToPlacement(const std::string id, int cardIndex){
- if(_placements.count(id) == 0)return false;
- if(cardIndex < 0 || cardIndex >= _placements[id].cards.size()){
- return false;
- }
- _placements[id].cards.erase(_placements[id].cards.begin() + cardIndex);
- return true;
- }
- void IAPCtlShopUI::clearPlacement(){
- _placements.clear();
- _indicators.clear();
- }
- size_t IAPCtlShopUI::getPlacementCount(){
- return _placements.size();
- }
- 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, iapshop::ShopRequirement& requirement) {
- 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;
- }
- // 开始构建
- // 获取礼包信息
- IAPConf::getInstance()->getAllGoods(_goodsInfo);
- // 获取版位信息
- int bigPackCount,smallPackCount; // 需要显示的礼包
- auto iapCtlShop = iapshop::IAPCtlShop::createWith();
- auto userBuyType = iapshop::IAPRunTimeData::getInstance()->getUserBuyType();
- int leval = iapshop::IAPRunTimeData::getInstance()->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;
- }
- // 展示活动礼包
- if(_placements.size() != 0){
- for(const auto& placement : _placements){
- bool isShow = false;
- if(bShowAll){
- isShow = true;
- }else{
- if(bigPackCount > 0){
- isShow = true;
- bigPackCount--;
- }
- }
- if(isShow){
- // 展示活动版位
- bool bNeedAnim = height <= size.height;
- Node* nd = Node::create();
- nd->setAnchorPoint(Vec2(0.5,0.5));
- nd->setContentSize(cocos2d::Size(584,250));
- nd->setCascadeOpacityEnabled(true);
- nd->setCascadeColorEnabled(true);
-
- auto si = createPlacementUI(placement.second);
- auto sz = cocos2d::Size(584,280);
- cocos2d::Vec2 pos(size.width/2.0, sz.height/2.0);
- nd->addChild(si);
- si->setPosition(bNeedAnim ? pos+offset : pos);
- _placementItems.push_back(nd);
- _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 ++;
- }
-
- }
-
- }
- }
- // 根据用户类型进行礼包排序
- switch (userBuyType) {
- case iapshop::UserBuyType::NoShopping:
- sortGoods(true);
- break;
- case iapshop::UserBuyType::LittleShopping:
- sortGoods(true);
- break;
- case iapshop::UserBuyType::NormalShopping:
- sortGoods(true);
- break;
- case iapshop::UserBuyType::LotShopping:
- sortGoods(false);
- break;
- default:
- break;
- }
- // 判断是否展示全部
- if(!bShowAll){
- // 不展示全部,过滤掉不合格的礼包
- filterGoods(requirement);
- }
- // 判断是否为正常消费
- if(userBuyType == iapshop::UserBuyType::NormalShopping && !bShowAll){
- // (当前已按 大礼包 > 小礼包,金额小 > 金额大 的优先级排序)
- // 获取购买过的最大金额
- float maxn = iapshop::IAPRunTimeData::getInstance()->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(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 ++;
- }
- }
- 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(_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 ++;
- }
- }
- 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, 这个是一定会有动画的
- 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();
- _placementItems.clear();
- for(const auto& placement : _placements){
- _indicators[placement.first].clear();
- }
- _allSizes.clear();
-
- iapshop::ShopRequirement req;
- req.coinsMin = 0;
- constructShopItem(true, req);
-
- _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");
- }
- Node* IAPCtlShopUI::createPlacementUI(const iapshop::IAPPlacement& placement){
- Node* node = Node::create();
-
- IAPCardView::sDotCfg cfg;
- cfg.hightSp = "内购版位_通用_图标_滑动点_已选中.png";
- cfg.normalSp = "内购版位_通用_图标_滑动点_未选中.png";
- cfg.sepWidth = 30.0f;
- cfg.yStart = 0;
- cocos2d::Size sz = cocos2d::Size(584, 250);
- IAPCardView* cardView = IAPCardView::create(sz, cfg);
-
- // 遍历 placement 中的卡片,依次创建并添加到 PageView 中
- for (int i = 0; i < placement.cards.size(); i++) {
- cardView->addCard(placement.cards[i]->create());
- }
- // 将 PageView 添加到父节点 node 中
- node->addChild(cardView);
-
- return node;
- }
- void IAPCtlShopUI::filterGoods(iapshop::ShopRequirement &requirement){
- std::map<int, bool> m;
- int cnt = 0;
- for(const auto& goodInfo : _goodsInfo){
- if(goodInfo.getCoinNumber() >= requirement.coinsMin){
- m[cnt] = true;
- }
- 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.getTypeValue() != b.getTypeValue())return a.getTypeValue() > b.getTypeValue();
- if(flag) return a.getCostNumber() < b.getCostNumber();
- else return a.getCostNumber() > b.getCostNumber();
- });
-
- }
- void IAPCtlShopUI::quit() {
- if (_layer) {
- _layer->runBehaviacWhitFunName("退出");
- }
- }
|