932 lines
32 KiB
PHP
932 lines
32 KiB
PHP
<?php
|
|
|
|
require_once('mt/MarketGoods.php');
|
|
require_once('mt/MarketBatch.php');
|
|
require_once('mt/Item.php');
|
|
require_once('mt/WhiteList.php');
|
|
require_once('mt/Currency.php');
|
|
require_once('mt/Hero.php');
|
|
require_once('mt/Parameter.php');
|
|
|
|
require_once('models/BoxOrder.php');
|
|
require_once('models/Nft.php');
|
|
require_once('models/Hero.php');
|
|
require_once('models/Gun.php');
|
|
require_once('models/Chip.php');
|
|
require_once('models/Fragment.php');
|
|
require_once('models/BuyRecord.php');
|
|
require_once('models/BcOrder.php');
|
|
|
|
require_once('services/MarketService.php');
|
|
require_once('services/LuckyBoxService.php');
|
|
require_once('services/ActivateNftService.php');
|
|
require_once('services/BlockChainService.php');
|
|
require_once('services/LogService.php');
|
|
require_once('services/AwardService.php');
|
|
require_once('services/PropertyChgService.php');
|
|
|
|
require_once('phpcommon/bchelper.php');
|
|
|
|
|
|
// use phpcommon as phpcommon;
|
|
|
|
use models\BcOrder;
|
|
use phpcommon\SqlHelper;
|
|
use models\BoxOrder;
|
|
use models\Nft;
|
|
use models\Hero;
|
|
use models\Gun;
|
|
use models\Chip;
|
|
use models\Fragment;
|
|
use models\BuyRecord;
|
|
use services\MarketService;
|
|
use services\LuckyBoxService;
|
|
use services\ActivateNftService;
|
|
use models\Transaction;
|
|
use services\LogService;
|
|
|
|
class MarketController extends BaseAuthedController
|
|
{
|
|
private function getNftListByAccountAndType($account, $type, $order_method, $order_asc, $job, $search, $lv, $quality, $durability)
|
|
{
|
|
$sortByLevel = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['hero_lv'] - $a['detail']['hero_lv']);
|
|
};
|
|
$sortByGunLv = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['gun_lv'] - $a['detail']['gun_lv']);
|
|
};
|
|
$sortByTili = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['hero_tili'] - $a['detail']['hero_tili']);
|
|
};
|
|
$sortByStar = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['quality'] - $a['detail']['quality']);
|
|
};
|
|
$sortByDurability = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['durability_max'] - $a['detail']['durability_max']);
|
|
};
|
|
$sortByPower = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['strength'] - $a['detail']['strength']);
|
|
};
|
|
$sortByGrade = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['detail']['chip_grade'] - $a['detail']['chip_grade']);
|
|
};
|
|
$sortByTokenId = function ($a, $b) use ($order_asc) {
|
|
return ($order_asc == 1 ? 1 : -1) * ($b['token_id'] - $a['token_id']);
|
|
};
|
|
$nfts = array();
|
|
switch ($type) {
|
|
case Nft::NONE_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;
|
|
// if ($row['detail']['hero_lv'] < $lv) continue;
|
|
// if ($row['detail']['quality'] < $quality) continue;
|
|
// if ($row['detail']['hero_tili'] < $durability) continue;
|
|
if (count($search) > 0) {
|
|
$searchLower = array_map('strtolower', $search);
|
|
if (!(in_array(strtolower($row['detail']['hero_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue;
|
|
}
|
|
// $row['detail'] = $this->appendChipsInfo($row['detail']);
|
|
array_push($nfts, $row);
|
|
}
|
|
switch ($order_method) {
|
|
case 1:
|
|
usort($nfts, $sortByLevel);
|
|
break;
|
|
case 2:
|
|
usort($nfts, $sortByTili);
|
|
break;
|
|
case 3:
|
|
usort($nfts, $sortByStar);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
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 (!empty($job)) {
|
|
if (in_array($row['info']['info']['job'], $job) == false) continue;
|
|
}
|
|
if ($row['detail']['hero_lv'] < $lv) continue;
|
|
if ($row['detail']['quality'] < $quality) continue;
|
|
if ($row['detail']['hero_tili'] < $durability) continue;
|
|
if (count($search) > 0) {
|
|
$searchLower = array_map('strtolower', $search);
|
|
if (!(in_array(strtolower($row['detail']['hero_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue;
|
|
}
|
|
$row['detail'] = $this->appendChipsInfo($row['detail']);
|
|
array_push($nfts, $row);
|
|
}
|
|
switch ($order_method) {
|
|
case 1:
|
|
usort($nfts, $sortByLevel);
|
|
break;
|
|
case 2:
|
|
usort($nfts, $sortByTili);
|
|
break;
|
|
case 3:
|
|
usort($nfts, $sortByStar);
|
|
break;
|
|
}
|
|
}
|
|
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;
|
|
if ($row['detail']['quality'] < $quality) continue;
|
|
if ($row['detail']['durability'] < $durability) continue;
|
|
if (count($search) > 0) {
|
|
$searchLower = array_map('strtolower', $search);
|
|
if (!(in_array(strtolower($row['detail']['gun_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue;
|
|
}
|
|
$row['detail'] = $this->appendChipsInfo($row['detail']);
|
|
array_push($nfts, $row);
|
|
}
|
|
switch ($order_method) {
|
|
case 1:
|
|
usort($nfts, $sortByGunLv);
|
|
break;
|
|
case 2:
|
|
usort($nfts, $sortByDurability);
|
|
break;
|
|
case 3:
|
|
usort($nfts, $sortByStar);
|
|
break;
|
|
}
|
|
}
|
|
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))
|
|
continue;
|
|
if ($row['detail']['chip_grade'] < $lv) continue;
|
|
if (count($search) > 0) {
|
|
$searchLower = array_map('strtolower', $search);
|
|
if (!(in_array(strtolower($row['detail']['chip_name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue;
|
|
}
|
|
array_push($nfts, $row);
|
|
}
|
|
switch ($order_method) {
|
|
case 1:
|
|
usort($nfts, $sortByGrade);
|
|
break;
|
|
case 2:
|
|
usort($nfts, $sortByPower);
|
|
break;
|
|
}
|
|
}
|
|
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;
|
|
if (count($search) > 0) {
|
|
$searchLower = array_map('strtolower', $search);
|
|
if (!(in_array(strtolower($row['detail']['name']), $searchLower) || in_array(strtolower($row['detail']['token_id']), $searchLower))) continue;
|
|
}
|
|
array_push($nfts, $row);
|
|
}
|
|
usort($nfts, $sortByTokenId);
|
|
}
|
|
break;
|
|
default: {
|
|
}
|
|
}
|
|
return $nfts;
|
|
}
|
|
|
|
public function listSellNfts()
|
|
{
|
|
$account = strtolower(getReqVal('account', ''));
|
|
$token = getReqVal('token', '');
|
|
$start = getReqVal('start', 0);
|
|
$page_size = getReqVal('page_size', 10);
|
|
$order_method = getReqVal('order_method', 0);
|
|
$order_asc = getReqVal('order_asc', 1);
|
|
$type = getReqVal('type', 1);
|
|
$job_filters = getReqVal('job_filters', '');
|
|
$job_filter_array = explode('|', $job_filters);
|
|
$search_filters = getReqVal('search_filters', '');
|
|
if ($search_filters != '') {
|
|
$search_filter_array = explode('|', $search_filters);
|
|
} else {
|
|
$search_filter_array = array();
|
|
}
|
|
|
|
$lv_filter = getReqVal('lv_filter', 0);
|
|
$quality_filter = getReqVal('quality_filter', 0);
|
|
$durability_filter = getReqVal('durability_filter', 0);
|
|
$amount_filter = getReqVal('amount_filter', 0);
|
|
$amount_filter_array = explode('|', $amount_filter);
|
|
$price_filter = getReqVal('price_filter', '');
|
|
$price_filter_array = explode('|', $price_filter);
|
|
|
|
$job_filter_fn = function ($f) {
|
|
$str = '';
|
|
$arr = array();
|
|
foreach ($f as $v) {
|
|
if (!empty($v)) {
|
|
array_push($arr, 'c_job=\'' . $v . '\' ');
|
|
}
|
|
}
|
|
if (count($arr) > 0) {
|
|
$str = implode('OR ', $arr);
|
|
$str = 'AND (' . $str . ') ';
|
|
}
|
|
return $str;
|
|
};
|
|
$price_filter_fn = function ($f) {
|
|
if (count($f) == 2) {
|
|
$low = $f[0];
|
|
$top = $f[1];
|
|
return 'AND s_price>=' . $low . ' AND s_price<=' . $top . ' ';
|
|
}
|
|
return '';
|
|
};
|
|
$amount_filter_fn = function ($f) {
|
|
if (count($f) == 2) {
|
|
$low = $f[0];
|
|
$top = $f[1];
|
|
return 'AND amount>=' . $low . ' AND amount<=' . $top . ' ';
|
|
}
|
|
return '';
|
|
};
|
|
$lv_filter_fn = function ($f) {
|
|
$f = (int) $f;
|
|
return 'AND c_lv>=' . $f . ' ';
|
|
};
|
|
$quality_filter_fn = function ($f) {
|
|
$f = (int) $f;
|
|
return 'AND c_quality>=' . $f . ' ';
|
|
};
|
|
$durability_filter_fn = function ($f) {
|
|
$f = (int) $f;
|
|
return 'AND c_durability>=' . $f . ' ';
|
|
};
|
|
$search_filter_fn = function ($f) {
|
|
$str = '';
|
|
$arr_options = array();
|
|
foreach ($f as $v) {
|
|
if (!empty($v)) {
|
|
array_push($arr_options, 'c_name=\'' . $v . '\' OR token_id=\'' . $v . '\' ');
|
|
}
|
|
}
|
|
if (count($arr_options) > 0) {
|
|
$str = implode('OR ', $arr_options);
|
|
$str = 'AND (' . $str . ') ';
|
|
}
|
|
return $str;
|
|
};
|
|
|
|
$order_fn = function ($method, $asc) {
|
|
switch ($method) {
|
|
case 2:
|
|
return 'ORDER BY s_price ' . ($asc == 0 ? 'ASC' : 'DESC') . ' ';
|
|
break;
|
|
case 3:
|
|
return 'ORDER BY c_quality ' . ($asc == 0 ? 'ASC' : 'DESC') . ' ';
|
|
break;
|
|
case 4:
|
|
return 'ORDER BY c_lv ' . ($asc == 0 ? 'ASC' : 'DESC') . ' ';
|
|
break;
|
|
case 5:
|
|
return 'ORDER BY c_durability ' . ($asc == 0 ? 'ASC' : 'DESC') . ' ';
|
|
break;
|
|
|
|
// 所有其他不正常的排序都执行最新上架
|
|
case 1:
|
|
default:
|
|
return 'ORDER BY createtime ' . ($asc == 0 ? 'ASC' : 'DESC') . ' ';
|
|
break;
|
|
}
|
|
return '';
|
|
};
|
|
|
|
$conn = myself()->_getSelfMysql();
|
|
|
|
$counts = $conn->execQuery(
|
|
'SELECT count(idx) as count FROM t_market_store ' .
|
|
'WHERE token_type=:token_type AND status=0 ' .
|
|
$job_filter_fn($job_filter_array) .
|
|
$lv_filter_fn($lv_filter) .
|
|
$quality_filter_fn($quality_filter) .
|
|
$durability_filter_fn($durability_filter) .
|
|
$price_filter_fn($price_filter_array) .
|
|
$amount_filter_fn($amount_filter_array) .
|
|
$search_filter_fn($search_filter_array) .
|
|
$order_fn($order_method, $order_asc),
|
|
array(
|
|
':token_type' => $type,
|
|
)
|
|
);
|
|
|
|
$total = $counts[0]['count'];
|
|
$page_end = $start + $page_size;
|
|
if ($page_end > $total) {
|
|
$page_end = $total;
|
|
$start = $total - 1;
|
|
$start = intval($start / $page_size) * $page_size;
|
|
if ($start < 0) $start = 0;
|
|
}
|
|
|
|
$rows = $conn->execQuery(
|
|
'SELECT * FROM t_market_store ' .
|
|
'WHERE token_type=:token_type AND status=0 ' .
|
|
$job_filter_fn($job_filter_array) .
|
|
$lv_filter_fn($lv_filter) .
|
|
$quality_filter_fn($quality_filter) .
|
|
$durability_filter_fn($durability_filter) .
|
|
$price_filter_fn($price_filter_array) .
|
|
$amount_filter_fn($amount_filter_array) .
|
|
$search_filter_fn($search_filter_array) .
|
|
$order_fn($order_method, $order_asc) .
|
|
'LIMIT ' . $start . ',' . $page_size,
|
|
array(
|
|
':token_type' => $type,
|
|
)
|
|
);
|
|
|
|
$nfts = array();
|
|
|
|
for ($x = $start; $x < $page_end; $x++) {
|
|
$row = $rows[$x % $page_size];
|
|
$nftDb = Nft::getNft($row['token_id']);
|
|
if (!$nftDb) {
|
|
$nftDb = Nft::findNftByOwner($account, $row['token_id']);
|
|
// 0x768b5faed6dc69816f33377d214ffaf00dcdd0cf
|
|
if (!$nftDb) {
|
|
$nftDb = Nft::findNftByOwner('0xfc628dd79137395f3c9744e33b1c5de554d94882', $row['token_id']);
|
|
if (!$nftDb) {
|
|
if ($row['item_id']) {
|
|
} else {
|
|
myself()->_rspErr(1, 'nft not exists');
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$row['info'] = $nftDb ? Nft::toDto($nftDb) : null;
|
|
$row['detail'] = $nftDb ? $this->getNftGameData($nftDb) : null;
|
|
array_push($nfts, $row);
|
|
}
|
|
|
|
$this->_rspData(array(
|
|
"total" => $total,
|
|
"start" => $start,
|
|
"page_size" => $page_size,
|
|
'nfts' => $nfts,
|
|
));
|
|
}
|
|
|
|
public function listMyNfts()
|
|
{
|
|
$account = strtolower(getReqVal('account', ''));
|
|
$token = getReqVal('token', '');
|
|
$start = getReqVal('start', 0);
|
|
$page_size = getReqVal('page_size', 10);
|
|
$order_method = getReqVal('order_method', 0);
|
|
$order_asc = getReqVal('order_asc', 1);
|
|
$type = getReqVal('type', 1);
|
|
$job_filters = getReqVal('job_filters', '');
|
|
|
|
$address = $this->_getAddress();
|
|
if ($address != $account) {
|
|
$this->_rspErr(1, 'account not match');
|
|
return;
|
|
}
|
|
if (empty($job_filters)) {
|
|
$job_filter_array = array();
|
|
} else {
|
|
$job_filter_array = explode('|', $job_filters);
|
|
}
|
|
|
|
$search_filters = getReqVal('search_filters', '');
|
|
if ($search_filters != '') {
|
|
$search_filter_array = explode('|', $search_filters);
|
|
} else {
|
|
$search_filter_array = array();
|
|
}
|
|
|
|
$lv_filter = getReqVal('lv_filter', 0);
|
|
$quality_filter = getReqVal('quality_filter', 0);
|
|
$durability_filter = getReqVal('durability_filter', 0);
|
|
|
|
$rows = $this->getNftListByAccountAndType($account, $type, $order_method, $order_asc, $job_filter_array, $search_filter_array, $lv_filter, $quality_filter, $durability_filter);
|
|
|
|
$total = count($rows);
|
|
$page_end = $start + $page_size;
|
|
if ($page_end > $total) {
|
|
$page_end = $total;
|
|
$start = $total - 1;
|
|
$start = intval($start / $page_size) * $page_size;
|
|
if ($start < 0) $start = 0;
|
|
}
|
|
|
|
$nfts = array();
|
|
for ($x = $start; $x < $page_end; $x++) {
|
|
$row = $rows[$x];
|
|
// $this->attach_market_selling($row);
|
|
array_push($nfts, $row);
|
|
}
|
|
|
|
$this->_rspData(array(
|
|
"total" => $total,
|
|
"start" => $start,
|
|
"page_size" => $page_size,
|
|
'nfts' => $nfts,
|
|
));
|
|
}
|
|
|
|
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->markOrderBuying($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 markOrderBuying($idx)
|
|
{
|
|
$r = SqlHelper::update(
|
|
myself()->_getSelfMysql(),
|
|
't_market_store',
|
|
array(
|
|
'idx' => $idx,
|
|
),
|
|
array(
|
|
'status' => 3,
|
|
'buytime' => myself()->_getNowTime(),
|
|
)
|
|
);
|
|
if (!$r) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|