Merge branch 'james_bc' of git.kingsome.cn:server/game2006api into james_bc

This commit is contained in:
hujiabin 2023-01-11 13:30:52 +08:00
commit 4888f63011
3 changed files with 482 additions and 7 deletions

View File

@ -17,8 +17,17 @@ class NftIntro(object):
['c_job', 0, '缓存-职业'],
['c_lv', 0, '缓存-级别'],
['c_id', 0, '缓存-idx'],
['selling', 0, '正在售卖的个数'],
['o_link', '', '关联的售卖单号'],
['details', _common.NftDetail(), 'nft列表'],
]
class CurrencyType(object):
def __init__(self):
self.fields = [
['name', '', '货币名称'],
['address', '', '货币地址'],
]
class Market(object):
def __init__(self):
@ -397,4 +406,17 @@ class Market(object):
_common.RspHead()
]
},
{
'name': 'getSupportedCurrencyTypes',
'desc': '获取支持的货币类型',
'group': 'Market',
'url': 'webapp/index.php?c=Market&a=getSupportedCurrencyTypes',
'params': [
['account', '', '账号id'],
],
'response': [
_common.RspHead(),
['!list', [CurrencyType()], '货币类型列表'],
]
}
]

149
uml/market.drawio Normal file
View File

@ -0,0 +1,149 @@
<mxfile host="65bd71144e">
<diagram id="RhfSRgj28ZWy9lpzOC5h" name="Page-1">
<mxGraphModel dx="946" dy="807" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="45" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="41" target="44">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="80" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="41" target="79">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="41" value="User" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="40" y="200" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="55" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="42" target="54">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="42" value="User" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="40" y="550" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="49" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="44" target="48">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="44" value="调用上架合约" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="200" y="200" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="51" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="48" target="50">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="48" value="修改NFT Owner" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="400" y="200" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="53" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="50" target="52">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="50" value="同步NFT中心化数据 Owner" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="600" y="200" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="76" value="增加一个订单" style="edgeStyle=none;html=1;" edge="1" parent="1" source="52" target="63">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="52" value="同步中心化货架信息" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="800" y="200" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="70" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="54" target="69">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="54" value="购买NFT" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="200" y="550" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="60" value="" style="edgeStyle=none;html=1;" edge="1" parent="1" source="56" target="59">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="56" value="User" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="40" y="380" width="30" height="60" as="geometry"/>
</mxCell>
<mxCell id="59" value="检索上架NFT" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="200" y="430" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="77" style="edgeStyle=none;html=1;entryX=1;entryY=0;entryDx=0;entryDy=15;entryPerimeter=0;" edge="1" parent="1" source="61" target="63">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="78" value="为检索缓存NFT数据" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="77">
<mxGeometry x="0.0816" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="61" value="NFTs 721" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="830" y="780" width="60" height="80" as="geometry"/>
</mxCell>
<mxCell id="75" value="同步中心化NFT Owner" style="edgeStyle=none;html=1;" edge="1" parent="1" source="62" target="61">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="62" value="链上NFTs" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="590" y="780" width="60" height="80" as="geometry"/>
</mxCell>
<mxCell id="65" value="" style="edgeStyle=none;html=1;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="63" target="59">
<mxGeometry relative="1" as="geometry">
<mxPoint x="520" y="665" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="66" value="直接从货架表检索已上架的NFTs" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=30;" vertex="1" connectable="0" parent="65">
<mxGeometry x="-0.2491" y="4" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="86" style="edgeStyle=none;html=1;exitX=0.855;exitY=1;exitDx=0;exitDy=-4.35;exitPerimeter=0;" edge="1" parent="1" source="63" target="85">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="690" y="890"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="87" value="特殊性多个上架指向同一token" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="86">
<mxGeometry x="0.4509" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="63" value="Market货架" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="590" y="620" width="80" height="90" as="geometry"/>
</mxCell>
<mxCell id="71" style="edgeStyle=none;html=1;entryX=0;entryY=0;entryDx=0;entryDy=15;entryPerimeter=0;" edge="1" parent="1" source="69" target="62">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="72" value="成功后修改Owner" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=15;" vertex="1" connectable="0" parent="71">
<mxGeometry x="-0.3761" y="-2" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="73" style="edgeStyle=none;html=1;" edge="1" parent="1" source="69" target="63">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="74" value="成功后删除货架上的订单" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=-5;" vertex="1" connectable="0" parent="73">
<mxGeometry x="-0.0746" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="69" value="调用购买合约" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="200" y="690" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="81" style="edgeStyle=none;html=1;" edge="1" parent="1" source="79" target="62">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="82" value="成功后修改上架价格信息" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];rotation=60;" vertex="1" connectable="0" parent="81">
<mxGeometry x="-0.5924" y="-1" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="83" style="edgeStyle=none;html=1;" edge="1" parent="1" source="62" target="63">
<mxGeometry relative="1" as="geometry">
<mxPoint x="520" y="480" as="sourcePoint"/>
</mxGeometry>
</mxCell>
<mxCell id="84" value="同步货架售价" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="83">
<mxGeometry x="0.0058" y="-3" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="79" value="调用更新价格合约" style="whiteSpace=wrap;html=1;verticalAlign=top;" vertex="1" parent="1">
<mxGeometry x="200" y="280" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="85" value="NFTs 1155" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" vertex="1" parent="1">
<mxGeometry x="830" y="880" width="60" height="80" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -22,6 +22,7 @@ require_once('services/ActivateNftService.php');
require_once('phpcommon/bchelper.php');
// use phpcommon as phpcommon;
use phpcommon\SqlHelper;
use models\BoxOrder;
use models\Nft;
@ -571,8 +572,12 @@ class MarketController extends BaseController {
switch ($type) {
case Nft::HERO_TYPE: {
$rows = Nft::getNftListByType($account, $type);
$rows = array_merge($rows, $this->listMySelledNfts($account, $type));
foreach ($rows as &$row) {
$nftDb = Nft::findNftByOwner($account, $row['token_id']);
if (empty($nftDb)) {
$nftDb = Nft::getNft($row['token_id']);
}
$row['info'] = Nft::toDto($nftDb);
$row['detail'] = Hero::toDtoInfo(Hero::findByTokenId2($row['token_id']));
if (in_array($row['info']['info']['job'], $job)==false) continue;
@ -601,8 +606,12 @@ class MarketController extends BaseController {
break;
case Nft::EQUIP_TYPE: {
$rows = Nft::getNftListByType($account, $type);
$rows = array_merge($rows, $this->listMySelledNfts($account, $type));
foreach ($rows as &$row) {
$nftDb = Nft::findNftByOwner($account, $row['token_id']);
if (empty($nftDb)) {
$nftDb = Nft::getNft($row['token_id']);
}
$row['info'] = Nft::toDto($nftDb);
$row['detail'] = Gun::toDtoInfo(Gun::findByTokenId2($row['token_id']));
if ($row['detail']['gun_lv']<$lv) continue;
@ -630,6 +639,7 @@ class MarketController extends BaseController {
break;
case Nft::CHIP_TYPE: {
$rows = Nft::getNft1155List($account, $type);
$rows = array_merge($rows, $this->listMySelledNfts($account, $type));
foreach ($rows as &$row) {
$row['detail'] = Chip::toDto(Chip::getChipByTokenId($row['token_id']));
if (!in_array($row['detail']['chip_type'], $job))
@ -653,8 +663,12 @@ class MarketController extends BaseController {
break;
case Nft::FRAGMENT_TYPE: {
$rows = Nft::getNft1155List($account, $type);
$rows = array_merge($rows, $this->listMySelledNfts($account, $type));
foreach ($rows as &$row) {
$nftDb = Nft::findNftByOwner($account, $row['token_id']);
if (empty($nftDb)) {
$nftDb = Nft::getNft($row['token_id']);
}
$row['detail'] = $this->getNftGameData($nftDb);
if (!in_array($row['detail']['type'], $job))
continue;
@ -676,7 +690,7 @@ class MarketController extends BaseController {
public function listSellNfts()
{
$account = getReqVal('account', '');
$account = strtolower(getReqVal('account', ''));
$token = getReqVal('token', '');
$start = getReqVal('start', 0);
$page_size = getReqVal('page_size', 10);
@ -770,7 +784,7 @@ class MarketController extends BaseController {
$counts = $conn->execQuery(
'SELECT count(*) as count FROM t_market_store '.
'WHERE token_type=:token_type '.
'WHERE token_type=:token_type AND status=0 '.
$job_filter_fn($job_filter_array).
$lv_filter_fn($lv_filter).
$quality_filter_fn($quality_filter).
@ -794,7 +808,7 @@ class MarketController extends BaseController {
$rows = $conn->execQuery(
'SELECT * FROM t_market_store '.
'WHERE token_type=:token_type '.
'WHERE token_type=:token_type AND status=0 '.
$job_filter_fn($job_filter_array).
$lv_filter_fn($lv_filter).
$quality_filter_fn($quality_filter).
@ -812,10 +826,14 @@ class MarketController extends BaseController {
for ($x = $start; $x < $page_end; $x++) {
$row = $rows[$x%$page_size];
$nftDb = Nft::findNftByOwner($row['owner_address'], $row['token_id']);
$nftDb = Nft::getNft($row['token_id']);
if (!$nftDb) {
myself()->_rspErr(1, 'nft not exists');
return;
$nftDb = Nft::findNftByOwner($account, $row['token_id']);
// 0x768b5faed6dc69816f33377d214ffaf00dcdd0cf
if (!$nftDb) {
myself()->_rspErr(1, 'nft not exists');
return;
}
}
$nft = Nft::toDto($nftDb);
$row['info'] = $nft;
@ -867,6 +885,7 @@ class MarketController extends BaseController {
$nfts = array();
for ($x = $start; $x < $page_end; $x++) {
$row = $rows[$x];
// $this->attach_market_selling($row);
array_push($nfts, $row);
}
@ -936,6 +955,252 @@ class MarketController extends BaseController {
$this->_rspOk();
}
public function getSupportedCurrencyTypes() {
$types = array();
if (SERVER_ENV == _ONLINE) {
array_push($types, array(
'name' => 'USDT',
'address' => '0xc22Ffa318051d8aF4E5f2E2732d7049486fcE093',
));
array_push($types, array(
'name' => 'CEC',
'address' => '0x9561C133DD8580860B6b7E504bC5Aa500f0f06a7',
));
array_push($types, array(
'name' => 'CEG',
'address' => '0xc22Ffa318051d8aF4E5f2E2732d7049486fcE093',
));
} else {
array_push($types, array(
'name' => 'USDT',
'address' => '0xc22Ffa318051d8aF4E5f2E2732d7049486fcE093',
));
array_push($types, array(
'name' => 'D CEC',
'address' => '0x9561C133DD8580860B6b7E504bC5Aa500f0f06a7',
));
array_push($types, array(
'name' => 'D CEG',
'address' => '0x59d3631c86BbE35EF041872d502F218A39FBa150',
));
}
$this->_rspData(array(
'list' => $types,
));
}
public function eventSellOrder() {
$tokenId = getReqVal('tokenId', '');
$owner = strtolower(getReqVal('owner', ''));
$nftToken = getReqVal('nftToken', '');
$amount = getReqVal('amount', 0);
$orderId = getReqVal('orderId', '');
$currency = getReqVal('currency', '');
$price = getReqVal('price', '');
error_log("eventSellOrder:" . json_encode(
array(
'tokenId' => $tokenId,
'owner' => $owner,
'nftToken' => $nftToken,
'amount' => $amount,
'orderId' => $orderId,
'currency' => $currency,
'price' => $price,
),
JSON_PRETTY_PRINT
)
);
$conn = myself()->_getMysql('');
// 1. check order status
$chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId));
if (!empty($chk)) {
$this->_rspErr(1, 'repeat sell order, orderId='.$orderId);
return;
}
// 2. insert sell order to t_market_store
$nftDb = Nft::findNftByOwner($owner, $tokenId);
if (empty($nftDb)) {
$nftDb = Nft::getNft($tokenId);
}
$nftDetail = Nft::toDto($nftDb);
$detail = $this->getNftGameData($nftDb);
$r = SqlHelper::insert(
$conn,
't_market_store',
array(
'token_id' => $tokenId,
'o_link' => $orderId,
'nft_token' => $nftToken,
'status' => 0,
'owner_address' => $owner,
'token_type' => $nftDetail['type'],
'amount' => $amount,
'createtime' => myself()->_getNowTime(),
'modifytime' => myself()->_getNowTime(),
's_currency' => $currency,
's_price' => $price,
'c_name' => $nftDetail['info']['name'],
'c_job' => isset($nftDetail['info']['job']) ? $nftDetail['info']['job']
: (isset($detail['chip_type']) ? $detail['chip_type']
: (isset($detail['type'])?$detail['type']
:0)),
'c_lv' => @$detail['gun_lv'] | @$detail['hero_lv'] | @$detail['chip_grade'],
'c_quality' => isset($nftDetail['info']['quality']) ? $nftDetail['info']['quality'] : 0,
'c_durability' => isset($nftDetail['info']['durability']) ? $nftDetail['info']['durability'] : (isset($detail['hero_tili']) ? $detail['hero_tili'] : 0),
'c_type' => isset($detail['type']) ? $detail['type'] : 0,
'c_id' => $nftDetail['item_id'],
)
);
if (!$r) {
$this->_rspErr(2, 'unknown error, orderId='.$orderId);
}
$this->_rspOk();
}
public function eventBuyOrder() {
$tokenId = getReqVal('tokenId', '');
$orderId = getReqVal('orderId', '');
$nftToken = getReqVal('nftToken', '');
$amount = getReqVal('amount', 0);
$seller = strtolower(getReqVal('seller', ''));
$buyer = strtolower(getReqVal('buyer', ''));
$erc20 = getReqVal('erc20', '');
$price = getReqVal('price', '');
error_log("eventBuyOrder:" . json_encode(
array(
'tokenId' => $tokenId,
'orderId' => $orderId,
'nftToken' => $nftToken,
'amount' => $amount,
'seller' => $seller,
'buyer' => $buyer,
'erc20' => $erc20,
'price' => $price,
),
JSON_PRETTY_PRINT
)
);
$conn = myself()->_getMysql('');
// 1. check order status
$chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId));
if (empty($chk)) {
$this->_rspErr(1, 'not found order, orderId='.$orderId);
return;
}
if ($chk['status']== '0') {
$r = SqlHelper::update(
$conn,
't_market_store',
array(
'o_link' => $orderId,
),
array(
'status' => 2,
)
);
if ($r) {
$this->_rspOk();
return;
}
}
$this->_rspErr(1, 'order status error, order='.$orderId);
}
public function eventCancelOrder() {
$orderId = getReqVal('orderId', '');
$nftToken = getReqVal('nftToken', '');
$tokenId = getReqVal('tokenId', '');
error_log("eventCancelOrder:" . json_encode(
array(
'orderId' => $orderId,
'nftToken' => $nftToken,
'tokenId' => $tokenId,
),
JSON_PRETTY_PRINT
)
);
$conn = myself()->_getMysql('');
// 1. check order status
$chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId));
if (empty($chk)) {
$this->_rspErr(1, 'not found order, orderId='.$orderId);
return;
}
if ($chk['status']== '0') {
$r = SqlHelper::update(
$conn,
't_market_store',
array(
'o_link' => $orderId,
),
array(
'status' => 1,
)
);
if ($r) {
$this->_rspOk();
return;
}
}
$this->_rspErr(1, 'order status error, order='.$orderId);
}
public function eventPriceUpdateOrder() {
$orderId = getReqVal('orderId', '');;
$nftToken = getReqVal('nftToken', '');
$tokenId = getReqVal('tokenId', '');
$priceOld = getReqVal('priceOld', '');
$price = getReqVal('price', '');
error_log("eventPriceUpdateOrder:" . json_encode(
array(
'orderId' => $orderId,
'nftToken' => $nftToken,
'tokenId' => $tokenId,
'priceOld' => $priceOld,
'price' => $price,
),
JSON_PRETTY_PRINT
)
);
$conn = myself()->_getMysql('');
// 1. check order status
$chk = SqlHelper::selectOne($conn, 't_market_store', array('status'), array('o_link' => $orderId));
if (empty($chk)) {
$this->_rspErr(1, 'not found order, orderId='.$orderId);
return;
}
if ($chk['status']== '0') {
$r = SqlHelper::update(
$conn,
't_market_store',
array(
'o_link' => $orderId,
),
array(
's_price' => $price,
)
);
if ($r) {
$this->_rspOk();
return;
}
}
$this->_rspErr(1, 'price update failed, orderId='.$orderId);
}
private function getNftGameData($nftRowInfo) {
$t = $nftRowInfo['token_type'];
@ -959,7 +1224,6 @@ class MarketController extends BaseController {
return array('unknown' => 'unknown game data type, cannot find data');
}
private function appendChipsInfo($detail) {
$detail['chips_info'] = array();
if (!empty($detail['chip_ids'])) {
@ -974,4 +1238,44 @@ class MarketController extends BaseController {
}
return $detail;
}
private function attach_market_selling(&$row) {
$conn = myself()->_getMysql('');
$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)
{
$conn = myself()->_getMysql('');
$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;
}
}