From 331fe8c65fb22ed84cd852fdb9a08b9d441c15b1 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 3 Aug 2023 20:52:00 +0800 Subject: [PATCH] 1 --- webapp/controller/MallController.class.php | 488 +++++++++++++++++++ webapp/controller/MarketController.class.php | 463 +----------------- 2 files changed, 489 insertions(+), 462 deletions(-) create mode 100644 webapp/controller/MallController.class.php diff --git a/webapp/controller/MallController.class.php b/webapp/controller/MallController.class.php new file mode 100644 index 00000000..0f30839c --- /dev/null +++ b/webapp/controller/MallController.class.php @@ -0,0 +1,488 @@ +_getAddress(); + if (!$address) { + $this->_rspErr(1, 'address not found'); + return; + } + + $item_id = getReqVal('item_id', ''); + if ($item_id != V_ITEM_GOLD) { + $this->_rspErr(1, 'only support gold'); + return; + } + + $itemMeta = mt\Item::get($item_id); + if (!$itemMeta) { + $this->_rspErr(1, 'item_id not found'); + return; + } + + $s_price = getReqVal('s_price', ''); + if (empty($s_price)) { + $this->_rspErr(1, 's_price not found'); + return; + } + if (!is_numeric($s_price)) { + $this->_rspErr(1, 's_price must be number'); + return; + } + if ($s_price <= 0) { + $this->_rspErr(1, 's_price must > 0'); + return; + } + + $amount = getReqVal('amount', 1); + if (empty($amount)) { + $this->_rspErr(1, 'amount not found'); + return; + } + if (!is_numeric($amount)) { + $this->_rspErr(1, 'amount must be number'); + return; + } + if ($amount <= 0) { + $this->_rspErr(1, 'amount must > 0'); + return; + } + + $conn = myself()->_getSelfMysql(); + + // 检查是否有足够的物品 + $costItems = $this->makeCostItems($item_id, $amount); + $lackItem = null; + if (!$this->_hasEnoughItems($costItems, $lackItem)) { + $this->_rspErr(2, $this->_getLackItemErrMsg($lackItem)); + return; + } + $this->_decItems($costItems); + { + //埋点 + $event = [ + 'name' => LogService::MARKET_SELL_GOLD, + 'val' => $amount + ]; + LogService::consumeGold($event); + } + + $c_name = $itemMeta['name']; + $c_job = 0; + $c_lv = 0; + $c_quality = $itemMeta['quality']; + $c_durability = 0; + $c_type = 0; + $c_id = $item_id; + + $r = SqlHelper::insert( + $conn, + 't_market_store', + array( + 'token_id' => '', + 'item_id' => $item_id, + 'status' => 0, + 'owner_address' => $address, + 'token_type' => 0, + 'amount' => $amount, + 'createtime' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowTime(), + 's_price' => $s_price, + 'c_name' => $c_name, + 'c_job' => $c_job, + 'c_lv' => $c_lv, + 'c_quality' => $c_quality, + 'c_durability' => $c_durability, + 'c_type' => $c_type, + 'c_id' => $c_id, + ) + ); + if (!$r) { + $this->_rspErr(3, "sell failed"); + return; + } + $lastId = $this->lastInsertId($conn); + $order_id = $this->genOrderId($lastId); + $test = SqlHelper::update($conn, 't_market_store', array('idx' => $lastId), array('order_id' => $order_id)); + if (!$test) { + $this->_rspErr(6, "sell failed"); + return; + } + + $this->_rspOk(); + } + + private function genOrderId($id) + { + $order_id_base = date('YmdHis') . "10000000"; + $divIdx = phpcommon\bnToStr(gmp_mod($id, 9999999)); + $order_id = phpcommon\bnAdd_s($order_id_base, $divIdx); + return $order_id; + } + private function lastInsertId($conn) + { + $row = $conn->execQueryOne('SELECT LAST_INSERT_ID() as lastId;', array()); + return $row['lastId']; + } + + private function makeCostItems($item_id, $num) + { + $costItems = array( + array( + 'item_id' => $item_id, + 'item_num' => $num + ) + ); + return $costItems; + } + + public function sellCancel() + { + $idx = getReqVal('idx', ''); + + $address = $this->_getAddress(); + if (!$address) { + $this->_rspErr(1, 'address not found'); + return; + } + + $goods = $this->getGoodsByIdx($idx); + if (!$goods) { + $this->_rspErr(1, 'goods not found, idx:' . $idx); + return; + } + + if ($goods['owner_address'] != $address) { + $this->_rspErr(1, 'not your goods, idx:' . $idx); + return; + } + + $conn = $this->_getSelfMysql(); + $r = SqlHelper::update( + $conn, + 't_market_store', + array( + 'idx' => $idx, + ), + array( + 'status' => 1, + 'modifytime' => $this->_getNowTime(), + ) + ); + if ($r) { + $items = array( + array( + 'item_id' => $goods['item_id'], + 'item_num' => $goods['amount'], + ) + ); + $awardService = new services\AwardService(); + $propertyChgService = new services\PropertyChgService(); + $this->_addItems($items, $awardService, $propertyChgService); + + { + //埋点 + $event = [ + 'name' => LogService::MARKET_CANCEL_SELL_GOLD, + 'val' => $goods['amount'] + ]; + LogService::productGold($event); + } + + $this->_rspData( + array( + 'idx' => $idx, + 'property_chg' => $propertyChgService->toDto(), + ) + ); + } else { + $this->_rspErr(1, 'cancel failed'); + } + } + + public function sellUpdatePrice() + { + $idx = getReqVal('idx', ''); + $s_price = getReqVal('s_price', ''); + if (empty($s_price)) { + $this->_rspErr(1, 's_price not found'); + return; + } + if (!is_numeric($s_price)) { + $this->_rspErr(1, 's_price must be number'); + return; + } + + $address = $this->_getAddress(); + if (!$address) { + $this->_rspErr(1, 'address not found'); + return; + } + + $goods = $this->getGoodsByIdx($idx); + if (!$goods) { + $this->_rspErr(1, 'goods not found, idx:' . $idx); + return; + } + + if ($goods['owner_address'] != $address) { + $this->_rspErr(1, 'not your goods, idx:' . $idx); + return; + } + + $conn = $this->_getSelfMysql(); + $r = SqlHelper::update( + $conn, + 't_market_store', + array( + 'idx' => $idx, + ), + array( + 's_price' => $s_price, + 'modifytime' => $this->_getNowTime(), + ) + ); + if (!$r) { + $this->_rspErr(1, 'update price failed'); + return; + } + + $this->_rspOk(); + } + + public function buy() + { + $address = $this->_getAddress(); + if (!$address) { + $this->_rspErr(1, 'address not found'); + return; + } + + $idx = getReqVal('idx', ''); + $s_price = getReqVal('s_price', ''); + if (empty($s_price)) { + $this->_rspErr(1, 's_price not found'); + return; + } + if (!is_numeric($s_price)) { + $this->_rspErr(1, 's_price not number'); + return; + } + + $goods = $this->getGoodsByIdx($idx); + if (!$goods) { + $this->_rspErr(1, 'goods not found, idx:' . $idx); + return; + } + + if ($s_price != $goods['s_price']) { + $this->_rspErr(1, 'price not match, idx:' . $idx); + return; + } + + $response = services\BlockChainService::gameItemMarketBuy( + Transaction::BUY_GOODS_FROM_MARKET_ACTION_TYPE, + $goods['owner_address'], + $goods['s_price'], + $goods['item_id'], + $goods['amount'] + ); + + if (!$this->markOrderBuyStatus($idx)) { + $this->_rspErr(1, 'buy failed, update order status failed, idx:' . $idx); + return; + } + + $item_id = $goods['item_id']; + $item_count = $goods['amount']; + + BcOrder::upsert($response['trans_id'], array( + 'item_id' => $item_id, + 'item_num' => $item_count, + 'order_type' => 1, + 'price' => $this->Web3PriceLowFormat($goods['s_price']), + 'ext_data' => json_encode(array( + 'mode' => MARKET_BUY_MODE_NORMAL, + 'idx' => $idx, + 'order_id' => $goods['order_id'], + )), + )); + + $this->_rspData(array( + 'block_chain' => $response, + )); + } + + private function Web3PriceLowFormat($price) + { + $bn2 = phpcommon\bnInit('1000000000000000000'); + $ret_price = phpcommon\bnDiv($price, $bn2); + return phpcommon\bnToStr($ret_price); + } + + private function getNftGameData($nftRowInfo) + { + $t = $nftRowInfo['token_type']; + $token_id = $nftRowInfo['token_id']; + switch ($t) { + case Nft::HERO_TYPE: { + return $this->appendChipsInfo(Hero::toDtoInfo(Hero::findByTokenId2($token_id))); + } + break; + case Nft::EQUIP_TYPE: { + return $this->appendChipsInfo(Gun::toDtoInfo(Gun::findByTokenId2($token_id))); + } + break; + case Nft::CHIP_TYPE: { + return Chip::toDto(Chip::getChipByTokenId($token_id)); + } + break; + case Nft::FRAGMENT_TYPE: { + return Fragment::ToDto($nftRowInfo); + } + break; + default: { + } + break; + } + return array('unknown' => 'unknown game data type, cannot find data'); + } + + private function appendChipsInfo($detail) + { + $detail['chips_info'] = array(); + if (!empty($detail['chip_ids'])) { + $chips = explode('|', $detail['chip_ids']); + foreach ($chips as $chip) { + $chip_info = ""; + if (!empty($chip)) { + $chip_info = Chip::toDto(Chip::getChipByTokenId($chip)); + } + array_push($detail['chips_info'], $chip_info); + } + } + return $detail; + } + + private function attach_market_selling(&$row) + { + $conn = myself()->_getSelfMysql(); + + $rows = $conn->execQuery( + 'SELECT * FROM t_market_store ' . + 'WHERE token_id=:token_id AND owner_address=:owner_address AND status=:status', + array( + ':token_id' => $row['token_id'], + ':owner_address' => $row['owner_address'], + ':status' => 0, + ) + ); + + $count = 0; + $link_array = array(); + foreach ($rows as $r) { + $count += $r['amount']; + array_push($link_array, $r['o_link']); + } + + $row['o_link'] = implode('|', $link_array); + $row['selling'] = $count; + } + + private function listMySelledNfts($account, $type) + { + // error_log('listMySelledNfts ' . $account . ' ' . $type); + + $conn = myself()->_getSelfMysql(); + + $rows = $conn->execQuery( + 'SELECT * FROM t_market_store ' . + 'WHERE owner_address=:account AND token_type=:token_type AND status=0 ', + array( + ':account' => $account, + ':token_type' => $type, + ) + ); + + return $rows; + } + + private function normalizeWeb3Price($price) + { + $bn1 = phpcommon\bnInit($price * pow(10, 8)); + $bn2 = phpcommon\bnInit('1000000000000000000'); + $ret_price = phpcommon\bnDiv(phpcommon\bnMul($bn1, $bn2), pow(10, 8)); + + // error_log('normalizeWeb3Price: ' . $ret_price . ' ' . $price * pow(10, 8)); + return phpcommon\bnToStr($ret_price); + } + + private function getGoodsByIdx($idx) + { + $row = SqlHelper::selectOne( + myself()->_getSelfMysql(), + 't_market_store', + array('order_id', 'item_id', 'amount', 's_price', 'owner_address'), + array( + 'idx' => $idx, + 'status' => 0, + ) + ); + if (!$row) { + return null; + } + if (!$row['item_id']) { + return null; + } + return $row; + } + + private function markOrderBuyStatus($idx) + { + $r = SqlHelper::update( + myself()->_getSelfMysql(), + 't_market_store', + array( + 'idx' => $idx, + ), + array( + 'status' => 3, + 'buytime' => myself()->_getNowTime(), + ) + ); + if (!$r) { + return false; + } + + return true; + } + +} diff --git a/webapp/controller/MarketController.class.php b/webapp/controller/MarketController.class.php index a8f65898..18f8699f 100644 --- a/webapp/controller/MarketController.class.php +++ b/webapp/controller/MarketController.class.php @@ -16,9 +16,6 @@ require_once('services/LogService.php'); require_once('phpcommon/bchelper.php'); - -// use phpcommon as phpcommon; - use models\BcOrder; use phpcommon\SqlHelper; use models\Nft; @@ -29,8 +26,7 @@ use models\Fragment; use models\Transaction; use services\LogService; -class MarketController extends BaseAuthedController -{ +class MarketController extends BaseAuthedController { public function listSellNfts() { @@ -286,461 +282,4 @@ class MarketController extends BaseAuthedController )); } - public function sell() - { - $address = $this->_getAddress(); - if (!$address) { - $this->_rspErr(1, 'address not found'); - return; - } - - $item_id = getReqVal('item_id', ''); - if ($item_id != V_ITEM_GOLD) { - $this->_rspErr(1, 'only support gold'); - return; - } - - $itemMeta = mt\Item::get($item_id); - if (!$itemMeta) { - $this->_rspErr(1, 'item_id not found'); - return; - } - - $s_price = getReqVal('s_price', ''); - if (empty($s_price)) { - $this->_rspErr(1, 's_price not found'); - return; - } - if (!is_numeric($s_price)) { - $this->_rspErr(1, 's_price must be number'); - return; - } - if ($s_price <= 0) { - $this->_rspErr(1, 's_price must > 0'); - return; - } - - $amount = getReqVal('amount', 1); - if (empty($amount)) { - $this->_rspErr(1, 'amount not found'); - return; - } - if (!is_numeric($amount)) { - $this->_rspErr(1, 'amount must be number'); - return; - } - if ($amount <= 0) { - $this->_rspErr(1, 'amount must > 0'); - return; - } - - $conn = myself()->_getSelfMysql(); - - // 检查是否有足够的物品 - $costItems = $this->makeCostItems($item_id, $amount); - $lackItem = null; - if (!$this->_hasEnoughItems($costItems, $lackItem)) { - $this->_rspErr(2, $this->_getLackItemErrMsg($lackItem)); - return; - } - $this->_decItems($costItems); - { - //埋点 - $event = [ - 'name' => LogService::MARKET_SELL_GOLD, - 'val' => $amount - ]; - LogService::consumeGold($event); - } - - $c_name = $itemMeta['name']; - $c_job = 0; - $c_lv = 0; - $c_quality = $itemMeta['quality']; - $c_durability = 0; - $c_type = 0; - $c_id = $item_id; - - $r = SqlHelper::insert( - $conn, - 't_market_store', - array( - 'token_id' => '', - 'item_id' => $item_id, - 'status' => 0, - 'owner_address' => $address, - 'token_type' => 0, - 'amount' => $amount, - 'createtime' => myself()->_getNowTime(), - 'modifytime' => myself()->_getNowTime(), - 's_price' => $s_price, - 'c_name' => $c_name, - 'c_job' => $c_job, - 'c_lv' => $c_lv, - 'c_quality' => $c_quality, - 'c_durability' => $c_durability, - 'c_type' => $c_type, - 'c_id' => $c_id, - ) - ); - if (!$r) { - $this->_rspErr(3, "sell failed"); - return; - } - $lastId = $this->lastInsertId($conn); - $order_id = $this->genOrderId($lastId); - $test = SqlHelper::update($conn, 't_market_store', array('idx' => $lastId), array('order_id' => $order_id)); - if (!$test) { - $this->_rspErr(6, "sell failed"); - return; - } - - $this->_rspOk(); - } - - private function genOrderId($id) - { - $order_id_base = date('YmdHis') . "10000000"; - $divIdx = phpcommon\bnToStr(gmp_mod($id, 9999999)); - $order_id = phpcommon\bnAdd_s($order_id_base, $divIdx); - return $order_id; - } - private function lastInsertId($conn) - { - $row = $conn->execQueryOne('SELECT LAST_INSERT_ID() as lastId;', array()); - return $row['lastId']; - } - - private function makeCostItems($item_id, $num) - { - $costItems = array( - array( - 'item_id' => $item_id, - 'item_num' => $num - ) - ); - return $costItems; - } - - public function sellCancel() - { - $idx = getReqVal('idx', ''); - - $address = $this->_getAddress(); - if (!$address) { - $this->_rspErr(1, 'address not found'); - return; - } - - $goods = $this->getGoodsByIdx($idx); - if (!$goods) { - $this->_rspErr(1, 'goods not found, idx:' . $idx); - return; - } - - if ($goods['owner_address'] != $address) { - $this->_rspErr(1, 'not your goods, idx:' . $idx); - return; - } - - $conn = $this->_getSelfMysql(); - $r = SqlHelper::update( - $conn, - 't_market_store', - array( - 'idx' => $idx, - ), - array( - 'status' => 1, - 'modifytime' => $this->_getNowTime(), - ) - ); - if ($r) { - $items = array( - array( - 'item_id' => $goods['item_id'], - 'item_num' => $goods['amount'], - ) - ); - $awardService = new services\AwardService(); - $propertyChgService = new services\PropertyChgService(); - $this->_addItems($items, $awardService, $propertyChgService); - - { - //埋点 - $event = [ - 'name' => LogService::MARKET_CANCEL_SELL_GOLD, - 'val' => $goods['amount'] - ]; - LogService::productGold($event); - } - - $this->_rspData( - array( - 'idx' => $idx, - 'property_chg' => $propertyChgService->toDto(), - ) - ); - } else { - $this->_rspErr(1, 'cancel failed'); - } - } - - public function sellUpdatePrice() - { - $idx = getReqVal('idx', ''); - $s_price = getReqVal('s_price', ''); - if (empty($s_price)) { - $this->_rspErr(1, 's_price not found'); - return; - } - if (!is_numeric($s_price)) { - $this->_rspErr(1, 's_price must be number'); - return; - } - - $address = $this->_getAddress(); - if (!$address) { - $this->_rspErr(1, 'address not found'); - return; - } - - $goods = $this->getGoodsByIdx($idx); - if (!$goods) { - $this->_rspErr(1, 'goods not found, idx:' . $idx); - return; - } - - if ($goods['owner_address'] != $address) { - $this->_rspErr(1, 'not your goods, idx:' . $idx); - return; - } - - $conn = $this->_getSelfMysql(); - $r = SqlHelper::update( - $conn, - 't_market_store', - array( - 'idx' => $idx, - ), - array( - 's_price' => $s_price, - 'modifytime' => $this->_getNowTime(), - ) - ); - if (!$r) { - $this->_rspErr(1, 'update price failed'); - return; - } - - $this->_rspOk(); - } - - public function buy() - { - $address = $this->_getAddress(); - if (!$address) { - $this->_rspErr(1, 'address not found'); - return; - } - - $idx = getReqVal('idx', ''); - $s_price = getReqVal('s_price', ''); - if (empty($s_price)) { - $this->_rspErr(1, 's_price not found'); - return; - } - if (!is_numeric($s_price)) { - $this->_rspErr(1, 's_price not number'); - return; - } - - $goods = $this->getGoodsByIdx($idx); - if (!$goods) { - $this->_rspErr(1, 'goods not found, idx:' . $idx); - return; - } - - if ($s_price != $goods['s_price']) { - $this->_rspErr(1, 'price not match, idx:' . $idx); - return; - } - - $response = services\BlockChainService::gameItemMarketBuy( - Transaction::BUY_GOODS_FROM_MARKET_ACTION_TYPE, - $goods['owner_address'], - $goods['s_price'], - $goods['item_id'], - $goods['amount'] - ); - - if (!$this->markOrderBuyStatus($idx)) { - $this->_rspErr(1, 'buy failed, update order status failed, idx:' . $idx); - return; - } - - $item_id = $goods['item_id']; - $item_count = $goods['amount']; - - BcOrder::upsert($response['trans_id'], array( - 'item_id' => $item_id, - 'item_num' => $item_count, - 'order_type' => 1, - 'price' => $this->Web3PriceLowFormat($goods['s_price']), - 'ext_data' => json_encode(array( - 'mode' => MARKET_BUY_MODE_NORMAL, - 'idx' => $idx, - 'order_id' => $goods['order_id'], - )), - )); - - $this->_rspData(array( - 'block_chain' => $response, - )); - } - - private function Web3PriceLowFormat($price) - { - $bn2 = phpcommon\bnInit('1000000000000000000'); - $ret_price = phpcommon\bnDiv($price, $bn2); - return phpcommon\bnToStr($ret_price); - } - - private function getNftGameData($nftRowInfo) - { - $t = $nftRowInfo['token_type']; - $token_id = $nftRowInfo['token_id']; - switch ($t) { - case Nft::HERO_TYPE: { - return $this->appendChipsInfo(Hero::toDtoInfo(Hero::findByTokenId2($token_id))); - } - break; - case Nft::EQUIP_TYPE: { - return $this->appendChipsInfo(Gun::toDtoInfo(Gun::findByTokenId2($token_id))); - } - break; - case Nft::CHIP_TYPE: { - return Chip::toDto(Chip::getChipByTokenId($token_id)); - } - break; - case Nft::FRAGMENT_TYPE: { - return Fragment::ToDto($nftRowInfo); - } - break; - default: { - } - break; - } - return array('unknown' => 'unknown game data type, cannot find data'); - } - - private function appendChipsInfo($detail) - { - $detail['chips_info'] = array(); - if (!empty($detail['chip_ids'])) { - $chips = explode('|', $detail['chip_ids']); - foreach ($chips as $chip) { - $chip_info = ""; - if (!empty($chip)) { - $chip_info = Chip::toDto(Chip::getChipByTokenId($chip)); - } - array_push($detail['chips_info'], $chip_info); - } - } - return $detail; - } - - private function attach_market_selling(&$row) - { - $conn = myself()->_getSelfMysql(); - - $rows = $conn->execQuery( - 'SELECT * FROM t_market_store ' . - 'WHERE token_id=:token_id AND owner_address=:owner_address AND status=:status', - array( - ':token_id' => $row['token_id'], - ':owner_address' => $row['owner_address'], - ':status' => 0, - ) - ); - - $count = 0; - $link_array = array(); - foreach ($rows as $r) { - $count += $r['amount']; - array_push($link_array, $r['o_link']); - } - - $row['o_link'] = implode('|', $link_array); - $row['selling'] = $count; - } - - private function listMySelledNfts($account, $type) - { - // error_log('listMySelledNfts ' . $account . ' ' . $type); - - $conn = myself()->_getSelfMysql(); - - $rows = $conn->execQuery( - 'SELECT * FROM t_market_store ' . - 'WHERE owner_address=:account AND token_type=:token_type AND status=0 ', - array( - ':account' => $account, - ':token_type' => $type, - ) - ); - - return $rows; - } - - private function normalizeWeb3Price($price) - { - $bn1 = phpcommon\bnInit($price * pow(10, 8)); - $bn2 = phpcommon\bnInit('1000000000000000000'); - $ret_price = phpcommon\bnDiv(phpcommon\bnMul($bn1, $bn2), pow(10, 8)); - - // error_log('normalizeWeb3Price: ' . $ret_price . ' ' . $price * pow(10, 8)); - return phpcommon\bnToStr($ret_price); - } - - private function getGoodsByIdx($idx) - { - $row = SqlHelper::selectOne( - myself()->_getSelfMysql(), - 't_market_store', - array('order_id', 'item_id', 'amount', 's_price', 'owner_address'), - array( - 'idx' => $idx, - 'status' => 0, - ) - ); - if (!$row) { - return null; - } - if (!$row['item_id']) { - return null; - } - return $row; - } - - private function markOrderBuyStatus($idx) - { - $r = SqlHelper::update( - myself()->_getSelfMysql(), - 't_market_store', - array( - 'idx' => $idx, - ), - array( - 'status' => 3, - 'buytime' => myself()->_getNowTime(), - ) - ); - if (!$r) { - return false; - } - - return true; - } - }