diff --git a/webapp/controller/MarketController.class.php b/webapp/controller/MarketController.class.php index 41edf1c8..b899e5e4 100644 --- a/webapp/controller/MarketController.class.php +++ b/webapp/controller/MarketController.class.php @@ -19,6 +19,7 @@ require_once('models/BuyRecord.php'); require_once('services/MarketService.php'); require_once('services/LuckyBoxService.php'); require_once('services/ActivateNftService.php'); +require_once('services/BlockChainService.php'); require_once('phpcommon/bchelper.php'); @@ -34,6 +35,7 @@ use models\BuyRecord; use services\MarketService; use services\LuckyBoxService; use services\ActivateNftService; +use models\Transaction; class MarketController extends BaseController { @@ -888,9 +890,8 @@ class MarketController extends BaseController } } } - $nft = Nft::toDto($nftDb); - $row['info'] = $nft; - $row['detail'] = $this->getNftGameData($nftDb); + $row['info'] = $nftDb ? Nft::toDto($nftDb) : null; + $row['detail'] = $nftDb ? $this->getNftGameData($nftDb) : null; array_push($nfts, $row); } @@ -917,7 +918,7 @@ class MarketController extends BaseController } else { $job_filter_array = explode('|', $job_filters); } - + $search_filters = getReqVal('search_filters', ''); if ($search_filters != '') { $search_filter_array = explode('|', $search_filters); @@ -1042,6 +1043,33 @@ class MarketController extends BaseController $this->_rspOk(); } + public function buy() { + $account = strtolower(getReqVal('account', '')); + $idx = getReqVal('idx', ''); + + $goods = $this->getGoodsByIdx($idx); + if (!$goods) { + $this->_rspErr(1, 'goods not found, idx:' . $idx); + return; + } + + $response = services\BlockChainService::gameItemMallBuyWithAddress($account, + Transaction::BUY_GOODS_FROM_MARKET_ACTION_TYPE, + $goods['s_price'], + $goods['item_id'], + $goods['amount'] + ); + + if ($response['code'] != 0) { + $this->_rspErr(1, 'buy failed, code:' . $response['code'] . ', msg:' . $response['msg']); + return; + } + + $this->_rspData(array( + 'block_chain' => $response, + )); + + } private function sellMyNft() { @@ -1513,9 +1541,92 @@ class MarketController extends BaseController private function decItems($address, $item_id, $amount) { + $self = myself(); + if (!$self) { + return false; + } + + $userInfo = $this->getUserInfo($address, array('gold')); + $count = $this->getItemCount($item_id, $userInfo); + if ($count < $amount) { + return false; + } + + $r = $this->decItem($address, $item_id, $amount); + if (!$r) { + return false; + } + return true; } + private function decItem($address, $item_id, $amount) + { + $self = myself(); + if (!$self) { + return false; + } + switch ($item_id) { + case V_ITEM_GOLD: { + $r = $this->decGold($address, $amount); + if (!$r) { + return false; + } + } + break; + } + return true; + } + + private function decGold($address, $amount) + { + $self = myself(); + if (!$self) { + return false; + } + + $userInfo = $this->getUserInfo($address, array('gold')); + $count = $this->getItemCount(V_ITEM_GOLD, $userInfo); + if ($count < $amount) { + return false; + } + + $r = $this->updateUserInfo($address, array( + 'gold' => function () use ($amount) { + return "GREATEST(0, gold - ${amount})"; + }, + 'consume_gold' => function () use ($amount) { + return "consume_gold + ${amount}"; + } + )); + if (!$r) { + return false; + } + + return true; + } + + private function updateUserInfo($address, $fieldKv) + { + $self = myself(); + if (!$self) { + return false; + } + + $r = SqlHelper::update( + $self->_getMysql(''), + 't_user', + array( + 'address' => $address, + ), + $fieldKv + ); + if (!$r) { + return false; + } + + return true; + } private function getCostItem($address, $item_id) { $self = myself(); @@ -1598,4 +1709,21 @@ class MarketController extends BaseController // error_log('normalizeWeb3Price: ' . $ret_price . ' ' . $price * pow(10, 8)); return phpcommon\bnToStr($ret_price); } + + private function getGoodsByIdx($idx) { + $self = myself(); + if (!$self) { + return null; + } + + $row = SqlHelper::selectOne( + $self->_getMarketMysql(''), + 't_market_store', + array('item_id', 'amount', 's_price'), + array( + 'idx' => $idx + ) + ); + return $row; + } } diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index a25344c5..e73465cb 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -386,6 +386,8 @@ class ShopController extends BaseAuthedController $chk = $this->refreshDailySelectionWithMode($address, 1); if ($chk) { $this->_decItems($costItems); + + error_log("refreshDailySelection-------" . $address . "---" . $cost); $this->_rspData( array( 'cost' => $cost, @@ -400,7 +402,7 @@ class ShopController extends BaseAuthedController { $address = $this->_getAddress(); if (empty($address)) { - $this->_rspErr(2, 'address is empty'); + $this->_rspErr(3, 'address is empty'); return; } @@ -428,6 +430,8 @@ class ShopController extends BaseAuthedController $max_count = count($arrCosts); $cost = $count < $max_count ? $arrCosts[$count] : -1; + error_log('getDailySelectionList address: ' . $address . ' idx:'. $selection['idx'] . ' refresh_info:' . "{$count}/{$max_count}" . ' cost:' . $cost); + $this->_rspData( array( 'idx' => $selection['idx'], @@ -442,7 +446,7 @@ class ShopController extends BaseAuthedController { $address = $this->_getAddress(); if (empty($address)) { - $this->_rspErr(2, 'address is empty'); + $this->_rspErr(4, 'address is empty'); return; } $id = getReqVal('id', 0); @@ -665,7 +669,7 @@ class ShopController extends BaseAuthedController $account = $this->_getAccountId(); $address = $this->_getAddress(); if (empty($address)) { - $this->_rspErr(2, 'address is empty'); + $this->_rspErr(5, 'address is empty'); return; } diff --git a/webapp/models/Transaction.php b/webapp/models/Transaction.php index 1a0746a8..2b6f21e8 100644 --- a/webapp/models/Transaction.php +++ b/webapp/models/Transaction.php @@ -22,7 +22,8 @@ class Transaction extends BaseModel { const BUY_PASS_ACTION_TYPE = 102; const BUY_GOODS_ACTION_TYPE = 103; const RESET_HERO_LEVEL_TYPE = 104; - + const BUY_GOODS_FROM_MARKET_ACTION_TYPE = 105; + const BUY_END_ACTION_TYPE = 200; const CREATED_STATUS = 1; diff --git a/webapp/services/BlockChainService.php b/webapp/services/BlockChainService.php index e4bc30f5..e09769f7 100644 --- a/webapp/services/BlockChainService.php +++ b/webapp/services/BlockChainService.php @@ -83,6 +83,65 @@ class BlockChainService { } } + public static function gameItemMallBuyWithAddress($address, $actionType, $price, $itemId, $itemNum) + { + if (!($actionType > Transaction::BUY_BEGIN_ACTION_TYPE && + $actionType < Transaction::BUY_END_ACTION_TYPE)) { + error_log('gameItemMallBuy action_type error:' . $actionType); + myself()->_rspErr(500, 'server internal error 1'); + die(); + return; + } + $account = $address; + if (empty($account)) { + error_log('gameItemMallBuy address is emtpy:' . myself()->_getAccountId()); + myself()->_rspErr(500, 'server internal error 2'); + die(); + return; + } + $params = array( + 'c' => 'GameItemMall', + 'a' => 'buy', + 'account' => $account, + 'price' => $price, + ); + { + $url = self::getWeb3ServiceUrl(); + $response = ''; + if (!phpcommon\HttpClient::get + ($url, + $params, + $response)) { + myself()->_rspErr(500, 'server internal error 3, url:' . $url); + die(); + return; + } + error_log("gameItemMallBuy:" . $response . "url:" . $url); + $rspObj = json_decode($response, true); + if ($rspObj['errcode'] == 0) { + $transId = $rspObj['trans_id']; + // Transaction::add( + // $transId, + // $actionType, + // '', //$tokenId, + // '', //$tokenType, + // 0, //$itemUniId, + // $itemId, //$itemId, + // $itemNum, + // 1 + // ); + return array( + 'trans_id' => $transId, + 'params' => $rspObj['params'] + ); + } else { + myself()->_rspErr(500, 'server internal error 4' . json_encode($rspObj)); + die(); + return; + } + } + } + /* $price 是一个小数精确到小数点后5位 */ @@ -96,6 +155,9 @@ class BlockChainService { private static function getWeb3ServiceUrl() { + if (SERVER_ENV == _DEBUG) { + return 'http://login-test.kingsome.cn/webapp/index.php'; + } if (SERVER_ENV == _TEST) { return 'http://127.0.0.1:7672/webapp/index.php'; }