game2006api/webapp/controller/ShopController.class.php
aozhiwei e0f0f07987 1
2023-07-27 12:33:54 +08:00

1050 lines
35 KiB
PHP

<?php
require_once('mt/Shop.php');
require_once('mt/ShopGoods.php');
require_once('mt/Hero.php');
require_once('mt/Item.php');
require_once('mt/Parameter.php');
require_once('mt/Drop.php');
require_once('mt/PayMethod.php');
require_once('mt/Dailyselection.php');
require_once('mt/ShopChest.php');
require_once('models/User.php');
require_once('models/Hero.php');
require_once('models/Bag.php');
require_once('models/HeroSkin.php');
require_once('models/Gun.php');
require_once('models/GunSkin.php');
require_once('models/ShopBuyRecord.php');
require_once('models/Chip.php');
require_once('models/BcOrder.php');
require_once('models/Transaction.php');
require_once('services/AwardService.php');
require_once('services/PropertyChgService.php');
require_once('services/BlockChainService.php');
require_once('phpcommon/bignumber.php');
require_once('services/LogService.php');
require_once('services/callback/ShopAddItemService.php');
use models\User;
use models\Bag;
use models\Hero;
use models\HeroSkin;
use models\Gun;
use models\GunSkin;
use models\ShopBuyRecord;
use models\Chip;
use mt\Shop;
use mt\PayMethod;
use mt\Dailyselection;
use mt\ShopChest;
use mt\ShopGoods;
use models\Transaction;
use models\BcOrder;
use services\LogService;
use services\ShopAddItemService;
class ShopController extends BaseAuthedController
{
const TOKEN_TYPE_GOLD = '0';
const TOKEN_TYPE_CEG = '1';
const TOKEN_TYPE_CEC = '2';
const TOKEN_TYPE_BCEG = '3';
const TOKEN_TYPE_DIAMOND = '4';
const TOKEN_TYPE_USDT = '11';
const TOKEN_TYPE_USDC = '12';
const TOKEN_TYPE_BUSD = '13';
const TOKEN_TYPE_MATIC = '101';
const TOKEN_TYPE_BNB = '102';
//99 = 美元
const TOKEN_TYPE_USD = '99';
//21 = 印尼
const TOKEN_TYPE_IDR = '21';
//22 = 菲律宾
const TOKEN_TYPE_PHP = '22';
//23 = 越南
const TOKEN_TYPE_VND = '23';
//24 = 泰国
const TOKEN_TYPE_THB = '24';
//25 = 马来西亚
const TOKEN_TYPE_MYR = '25';
//26 = 日本
const TOKEN_TYPE_JPY = '26';
//27 = 韩国
const TOKEN_TYPE_KRW = '27';
// 限购类型
const DAILY_BUY_LIMIT = 1;
const WEEKLY_BUY_LIMIT = 2;
const TOTAL_BUY_LIMIT = 3;
public function getGoodsList()
{
$shop_id = getReqVal('shop_id', 0);
if ($shop_id == 0) {
$goodsList = mt\ShopGoods::all();
} else {
$goodsList = mt\ShopGoods::getGoodsList($shop_id);
}
$goodsList = $goodsList ? $goodsList : array();
$buyRecordHash = ShopBuyRecord::allToHash();
foreach ($goodsList as &$goods) {
$goods['bought_times'] = 0;
switch ($goods['limit_type']) {
case mt\Item::DAILY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goods['id']);
$goods['bought_times'] = $buyRecord ? $buyRecord['this_day_buy_times'] : 0;
}
break;
case mt\Item::WEEKLY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goods['id']);
$goods['bought_times'] = $buyRecord ? $buyRecord['this_week_buy_times'] : 0;
}
break;
case mt\Item::TOTAL_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $goods['id']);
$goods['bought_times'] = $buyRecord ? $buyRecord['total_buy_times'] : 0;
}
break;
default: {
}
break;
}
$goods_id = $goods['goods_id'];
$itemMeta = mt\Item::get($goods_id);
if ($itemMeta) {
// 如果是皮肤,判断是否已经拥有,如果已经拥有,不能购买
if ($itemMeta['type'] == mt\Item::HERO_SKIN_TYPE) {
$errCode = 0;
$errMsg = '';
if (!$this->canBuy($itemMeta, $errCode, $errMsg)) {
$goods['bought_times'] = 1;
} else {
$goods['bought_times'] = 0;
}
}
} else {
// error !!!!!!
error_log('item not found:' . $goods_id);
}
if (empty($goods['goods_num'])) {
$goods['goods_num'] = 1;
}
if (!empty($goods['free_type'])) {
$count = $this->countFreeBuyTimes($goods['free_type'], $goods['id'], $goods['goods_id']);
$goods['free_num'] = $goods['free_num'] - $count;
// error_log('free_num:' . $goods['free_num']);
}
$address = $this->_getAddress();
if ($address) {
// $goods['pending'] = $this->checkPendingBuyGoodsNormal($address, $goods['goods_id'], $goods['shop_id'], $goods['id']);
$goods['pending'] = 0;
}
}
$this->_rspData(
array(
'goods_list' => $goodsList,
)
);
}
public function startGoodsDirect()
{
$id = getReqVal('id', 0);
$token_type = getReqVal('token_type', '');
$goods_num = getReqVal('goods_num', 1);
if ($goods_num <= 0) {
$this->_rspErr(1, 'goods_num is invalid');
return;
}
$goods = mt\ShopGoods::get($id);
if (!$goods) {
$this->_rspErr(1, "id is invalid. {$id}");
return;
}
if ($goods['shop_id'] == 9 && $goods_num > 1) {
$this->_rspErr(1, 'goods_num is invalid');
return;
}
$conn = myself()->_getSelfMysql();
$address = myself()->_getAddress();
if (!$address) {
$this->_rspErr(1, 'address is empty');
return;
}
$chk = SqlHelper::insert(
$conn,
't_shop_buy_order',
array(
'address' => $address,
'createtime' => myself()->_getNowTime(),
'id' => $id,
'item_id' => $goods['goods_id'] ? $goods['goods_id'] : 0,
'goods_num' => $goods_num,
'status' => 0, // 0-客户端申请了订单 1-订单完成 2-订单失败
)
);
if ($chk) {
$lastId = $this->lastInsertId($conn);
$order_id = $this->genOrderId($lastId);
SqlHelper::update(
$conn,
't_shop_buy_order',
array(
'idx' => $lastId,
),
array(
'order_id' => $order_id,
)
);
$this->_rspData(
array(
'order_id' => $order_id,
)
);
} else {
$this->_rspErr(1, "insert error, id: {$id}, token_type: {$token_type}, goods_num: {$goods_num}");
}
}
public function statusGoodsDirect()
{
$order_id = getReqVal('order_id', '');
$conn = myself()->_getMysql('');
$row = SqlHelper::selectOne(
$conn,
't_shop_buy_order',
array('status', 'id'),
array(
'order_id' => $order_id,
)
);
if ($row) {
$this->_rspData(
array(
'status' => $row['status'],
'item_id' => $row['item_id'],
'item_num' => $row['goods_num'],
)
);
} else {
$this->_rspErr(1, "order_id not found, order_id: {$order_id}");
}
}
public function startInappPurchase()
{
$self = myself();
if (!$self) {
$this->_rspErr(1, "start purchase failed");
return;
}
$id = getReqVal('id', 0);
$goods = mt\ShopGoods::get($id);
if (!$goods) {
$this->_rspErr(2, "start purchase failed");
return;
}
if ($goods['shop_id'] != 9) {
$this->_rspErr(3, "start purchase failed");
return;
}
$goods_num = getReqVal('goods_num', 1);
$account_id = $self->_getAccountId();
$address = $self->_getAddress();
if (empty($address)) {
$this->_rspErr(4, "start purchase failed");
return;
}
$item_id = $goods['goods_id'];
$item_num = $goods['goods_num'] * $goods_num;
$conn = $self->_getMysql('');
$chk = SqlHelper::insert($conn, 't_web2_order', array(
'status' => 0,
'createtime' => $self->_getNowTime(),
'account_id' => $account_id,
'address' => $address,
'item_id' => $item_id,
'item_num' => $item_num,
'id' => $id,
'goods_num' => $goods_num,
'price' => $goods['price'],
));
if (!$chk) {
$this->_rspErr(5, "start purchase failed");
return;
}
$lastId = $this->lastInsertId($conn);
$order_id = $this->genOrderId($lastId);
$test = SqlHelper::update($conn, 't_web2_order', array('idx' => $lastId), array('order_id' => $order_id));
if (!$test) {
$this->_rspErr(6, "start purchase failed");
return;
}
$this->_rspData(array(
'order_id' => $order_id,
));
}
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;
}
public function statusInappPurchase()
{
$order_id = getReqVal('order_id', '');
$conn = myself()->_getMysql('');
$order = SqlHelper::selectOne($conn, 't_web2_order', array('item_id', 'item_num', 'status'), array('order_id' => $order_id));
if (!$order) {
$this->_rspErr(1, "order not found");
return;
}
$this->_rspData($order);
}
public function getPayMethods()
{
$token_type = getReqVal('token_type', 99);
$payMethods = mt\PayMethod::getPayMethods($token_type);
$this->_rspData(
array(
'pay_methods' => $payMethods,
)
);
}
public function buyGoodsNormal()
{
$address = $this->_getAddress();
if (empty($address)) {
$this->_rspErr(4, 'address is empty');
return;
}
$id = getReqVal('id', 0);
$token_type = getReqVal('token_type', '');
$goods_num = getReqVal('goods_num', 0);
if ($goods_num < 1) {
$this->_rspErr(1, "goods_num parameter error, goods_num: {$goods_num}");
return;
}
$row = mt\ShopGoods::get($id);
if (!$row) {
$this->_rspErr(1, 'goods not found');
return;
}
$goods_id = $row['goods_id'];
if (!empty($address)) {
// $pending = $this->checkPendingBuyGoodsNormal($address, $goods_id, $row['shop_id'], $id);
// if ($pending) {
// $this->_rspErr(1, 'pending');
// return;
// }
}
$desired_token_type = $row['token_type'];
$check_token_type = splitStr1($desired_token_type);
$token_pos = array_search($token_type, $check_token_type, true);
$isFreeBuy = false;
if (!empty($row['free_type'])) {
$count = $this->countFreeBuyTimes($row['free_type'], $row['id'], $row['goods_id']);
if ($count < $row['free_num']) {
$isFreeBuy = true;
}
}
if (!$isFreeBuy) {
if (!in_array($token_type, $check_token_type)) {
$this->_rspErr(1, "token_type parameter error, desired_token_type: {$desired_token_type}");
return;
}
}
if ($goods_num > $row['max_amount']) {
$this->_rspErr(1, "goods_num parameter error, max_amount: {$row['max_amount']}");
return;
}
// 这里命名混乱了, 购买个数,一捆个数命名冲突
$goods_count = $row['goods_num'];
$buyRecordHash = ShopBuyRecord::allToHash();
$boughtTimes = 1;
$itemMeta = mt\Item::get($row['goods_id']);
if (!$itemMeta) {
$this->_rspErr(1, 'goods not found, goods_id: ' . $row['goods_id']);
return;
}
if ($itemMeta['type'] == mt\Item::HERO_SKIN_TYPE) {
$errCode = 0;
$errMsg = '';
if (!$this->canBuy($itemMeta, $errCode, $errMsg)) {
$this->_rspErr($errCode, $errMsg);
return;
}
} else {
switch ($row['limit_type']) {
case ShopController::DAILY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['this_day_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'this_day_buy_times', 0) >= $row['limit_num']) {
$this->_rspErr(2, 'Daily purchase limit');
return;
}
}
break;
case ShopController::WEEKLY_BUY_LIMIT: {
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['this_week_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'this_week_buy_times', 0) >= $row['limit_num']) {
$this->_rspErr(2, 'Weekly purchase limit reached');
return;
}
}
break;
case ShopController::TOTAL_BUY_LIMIT: {
// error_log("total buy limit " . $address . " " . $id . " " . $row['limit_num']);
$buyRecord = getXVal($buyRecordHash, $id);
$boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1;
if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $row['limit_num']) {
$this->_rspErr(2, 'Purchase limit reached');
return;
}
}
break;
default: {
}
break;
}
}
$price_array = splitStr1($row['price']);
$discount_array = splitStr1($row['discount']);
$need_price = $price_array[$token_pos];
$discount = $discount_array[$token_pos];
$discount_begin = strtotime($row['discount_begin']);
$discount_end = strtotime($row['discount_end']);
$nowTime = $this->_getNowTime();
if ($nowTime >= $discount_begin && $nowTime < $discount_end) {
$need_price = ceil($need_price * ($discount / 100.0));
}
$costItemId = $this->getCostItemIdByTokenType($token_type);
switch ($token_type) {
case ShopController::TOKEN_TYPE_GOLD:
$costItems = $this->makeCostItems($costItemId, $goods_num * $need_price);
$lackItem = null;
if (!$this->_hasEnoughItems($costItems, $lackItem)) {
$this->_rspErr(2, $this->_getLackItemErrMsg($lackItem));
return;
}
$itemMeta = mt\Item::get($row['goods_id']);
$propertyChgService = new services\PropertyChgService();
for ($i = 0; $i < $goods_num; $i++) {
$this->internalAddItem($propertyChgService, $itemMeta, $goods_count, 0);
}
$awardService = new services\AwardService();
$awardService->addItem($row['goods_id'], $goods_num);
ShopBuyRecord::add($id, $goods_num);
$this->_decItems($costItems);
$goodsDto = array(
'goods_id' => $id,
'item_id' => $row['goods_id'],
'price_info' => array(
'item_id' => $row['goods_id'],
'cost_list' => array(),
'discount_begin_time' => phpcommon\datetimeToTimestamp($row['discount_begin']),
'discount_end_time' => phpcommon\datetimeToTimestamp($row['discount_end'])
),
'flag_icon' => $row['tag'],
'limit_type' => $row['limit_type'],
'bought_times' => $boughtTimes,
'total_buy_times' => $row['limit_num'],
); {
$priceInfo = mt\Item::getPriceInfo($itemMeta);
if (!empty($priceInfo)) {
$goodsDto['price_info'] = $priceInfo['price_info'];
}
}
$propertyChgService->addUserChg();
$this->_rspData(
array(
'award' => $awardService->toDto(),
'property_chg' => $propertyChgService->toDto(),
'goods_chg' => $goodsDto
)
);
break;
case ShopController::TOKEN_TYPE_DIAMOND:
if ($isFreeBuy) {
$need_price = 0;
}
$costItems = $this->makeCostItems($costItemId, $goods_num * $need_price);
$lackItem = null;
if (!$this->_hasEnoughItems($costItems, $lackItem)) {
$this->_rspErr(2, $this->_getLackItemErrMsg($lackItem));
return;
}
$itemMeta = mt\Item::get($row['goods_id']);
$propertyChgService = new services\PropertyChgService();
for ($i = 0; $i < $goods_num; $i++) {
$this->internalAddItem($propertyChgService, $itemMeta, $goods_count, 0);
}
$awardService = new services\AwardService();
$awardService->addItem($row['goods_id'], $goods_num);
ShopBuyRecord::add($id, $goods_num);
if ($isFreeBuy) {
$this->addFreeBuyRecord($row);
}
$this->_decItems($costItems);
$event = [
'name' => LogService::SHOP_BUY_ITEM,
'val' => $costItems[0]['item_num']
];
LogService::consumeDiamond($event);
$goodsDto = array(
'goods_id' => $id,
'item_id' => $row['goods_id'],
'price_info' => array(
'item_id' => $row['goods_id'],
'cost_list' => array(),
'discount_begin_time' => phpcommon\datetimeToTimestamp($row['discount_begin']),
'discount_end_time' => phpcommon\datetimeToTimestamp($row['discount_end'])
),
'flag_icon' => $row['tag'],
'limit_type' => $row['limit_type'],
'bought_times' => $boughtTimes,
'total_buy_times' => $row['limit_num'],
); {
$priceInfo = mt\Item::getPriceInfo($itemMeta);
if (!empty($priceInfo)) {
$goodsDto['price_info'] = $priceInfo['price_info'];
}
}
$propertyChgService->addUserChg();
$this->_rspData(
array(
'award' => $awardService->toDto(),
'property_chg' => $propertyChgService->toDto(),
'goods_chg' => $goodsDto
)
);
break;
case ShopController::TOKEN_TYPE_CEG:
case ShopController::TOKEN_TYPE_CEC:
if ($isFreeBuy) {
$propertyChgService = new services\PropertyChgService();
$this->addFreeBuyRecord($row);
$itemMeta = mt\Item::get($row['goods_id']);
$this->internalAddItem($propertyChgService, $itemMeta, $goods_count, 1);
$this->_rspOk();
} else {
$price = $this->normalizeWeb3Price($goods_num * $need_price);
$item_id = $row['goods_id'];
$item_count = $goods_num;
$response = services\BlockChainService::gameItemMallBuy(
Transaction::BUY_GOODS_ACTION_TYPE,
$price,
$item_id,
$item_count
);
BcOrder::upsert($response['trans_id'], array(
'item_id' => $item_id,
'item_num' => $item_count,
'order_type' => 1,
'price' => $goods_num * $need_price,
'ext_data' => json_encode(array(
'mode' => SHOP_BUY_MODE_NORMAL,
'shop_id' => $row['shop_id'],
'id' => $id,
)),
));
$response['item_id'] = $item_id;
$response['item_num'] = $item_count;
error_log("buy normal, item_id = " . $item_id . " item_count = " . $item_count . " need_price = " . $need_price . " price = " . $price . " response = " . json_encode($response));
$this->_rspData(
array(
"block_chain" => $response
)
);
}
break;
case ShopController::TOKEN_TYPE_BCEG:
break;
case ShopController::TOKEN_TYPE_USDT:
case ShopController::TOKEN_TYPE_USDC:
case ShopController::TOKEN_TYPE_BUSD:
case ShopController::TOKEN_TYPE_MATIC:
case ShopController::TOKEN_TYPE_BNB:
default:
$this->_rspErr(1, "token_type is unsupport, {$token_type}");
}
}
public function buyDiamond()
{
$num = getReqVal('num', 0);
if (!is_numeric($num)) {
$this->_rspErr(1, "num is invalid, {$num}");
return;
}
if ($num <= 0) {
$this->_rspErr(1, "num is invalid, {$num}");
return;
}
$price = $this->normalizeWeb3Price($num);
$item_id = V_ITEM_DIAMOND;
$item_count = $num;
error_log("buy diamond start " . $num);
$response = services\BlockChainService::gameItemMallBuy(
Transaction::BUY_GOODS_ACTION_TYPE,
$price,
$item_id,
$item_count
);
BcOrder::upsert($response['trans_id'], array(
'item_id' => $item_id,
'item_num' => $item_count,
'order_type' => 1,
'price' => $num,
'ext_data' => json_encode(array(
'mode' => SHOP_BUY_MODE_NORMAL,
)),
));
$response['item_id'] = $item_id;
$response['item_num'] = $item_count;
error_log("buy diamond, item_id = " . $item_id . " item_count = " . $item_count . " num = " . $num . " price = " . $price . " response = " . json_encode($response));
$this->_rspData(
array(
"block_chain" => $response
)
);
}
public function getChestItems()
{
$id = getReqVal('id', 0);
$goods = mt\ShopGoods::get($id);
$goods_id = $goods['goods_id'];
$shop_id = $goods['shop_id'];
$meta = mt\Item::get($goods_id);
if ($meta['type'] != mt\Item::CHEST_BOX_TYPE) {
$this->_rspErr(2, 'goods_id is invalid');
return;
}
$chestType = $meta['sub_type'];
$itemStore = mt\ShopChest::getRandomItemListByChestType($chestType);
if (!$itemStore) {
$this->_rspErr(2, 'goods_id is invalid');
return;
}
$record = array();
foreach ($itemStore as $key => $value) {
foreach ($value as $k => $v) {
if (empty($record[$v['item_id']])) {
$record[$v['item_id']] = 0;
}
$record[$v['item_id']] += 1;
}
}
if (!empty($goods['free_type'])) {
$count = $this->countFreeBuyTimes($goods['free_type'], $goods['id'], $goods['goods_id']);
$goods['free_num'] = $goods['free_num'] - $count;
} else {
$goods['free_num'] = 0;
}
$free_num = $goods['free_num'];
$this->_rspData(
array(
'items' => array_keys($record),
'free_num' => $free_num,
'pending' => 0,
)
);
}
private function getCostItemIdByTokenType($token_type)
{
switch ($token_type) {
case ShopController::TOKEN_TYPE_GOLD:
return V_ITEM_GOLD;
break;
case ShopController::TOKEN_TYPE_DIAMOND:
return V_ITEM_DIAMOND;
break;
case ShopController::TOKEN_TYPE_CEG:
case ShopController::TOKEN_TYPE_BCEG:
case ShopController::TOKEN_TYPE_USDT:
case ShopController::TOKEN_TYPE_USDC:
case ShopController::TOKEN_TYPE_BUSD:
case ShopController::TOKEN_TYPE_MATIC:
case ShopController::TOKEN_TYPE_BNB:
default:
return -1;
}
}
private function makeCostItems($item_id, $num)
{
$costItems = array(
array(
'item_id' => $item_id,
'item_num' => $num
)
);
return $costItems;
}
private function internalAddItem($propertyChgService, $itemMeta, $count, $sysAdd, $grade = null)
{
switch ($itemMeta['type']) {
case mt\Item::HERO_TYPE: {
if (empty($grade)) {
$grade = 0;
}
switch ($grade) {
case 1: {
Hero::addHero1($itemMeta);
}
break;
case 2: {
Hero::addHero2($itemMeta);
}
break;
case 3: {
Hero::addHero3($itemMeta);
}
break;
default: {
Hero::addHero($itemMeta);
}
break;
}
$propertyChgService->addHeroChg();
$propertyChgService->addUserChg();
}
break;
case mt\Item::HERO_SKIN_TYPE: {
HeroSkin::addSkin($itemMeta);
$propertyChgService->addHeroSkinChg();
}
break;
case mt\Item::GUN_TYPE: {
Gun::addGun($itemMeta);
$propertyChgService->addGunChg();
}
break;
case mt\Item::GUN_SKIN_TYPE: {
GunSkin::addSkin($itemMeta);
$propertyChgService->addGunSkinChg();
}
break;
case mt\Item::CHIP_TYPE: {
Chip::addChip($itemMeta);
$propertyChgService->addChip();
}
break;
default: {
if ($this->_isVirtualItem($itemMeta['id'])) {
$this->_addVirtualItem($itemMeta['id'], $count, null, $propertyChgService);
$propertyChgService->addUserChg();
} else {
Bag::addItem($itemMeta['id'], $count);
$propertyChgService->addBagChg();
}
}
break;
}
}
private function canBuy($itemMeta, &$errCode, &$errMsg)
{
$errCode = 0;
$errMsg = '';
switch ($itemMeta['type']) {
case mt\Item::HERO_TYPE: {
$heroDb = Hero::find($itemMeta['id']);
if ($heroDb) {
$errCode = 10;
$errMsg = 'You already have the hero';
return false;
}
}
break;
case mt\Item::HERO_SKIN_TYPE: {
$heroSkinDb = HeroSkin::find($itemMeta['id']);
if ($heroSkinDb) {
$errCode = 10;
$errMsg = 'You already have the skin';
return false;
}
}
break;
case mt\Item::GUN_SKIN_TYPE: {
$gunSkinDb = GunSkin::find($itemMeta['id']);
if ($gunSkinDb) {
$errCode = 10;
$errMsg = 'You already have the skin';
return false;
}
}
break;
default: {
return true;
}
break;
}
return true;
}
private function beginFirstTupop($address = null)
{
if (!$address) {
$address = myself()->_getAddress();
}
$conn = myself()->_getMysql('');
$exist = SqlHelper::selectOne(
$conn,
't_first_topup',
array('address'),
array('address' => $address)
);
if ($exist) {
return;
}
// 开始首充奖励活动进程
$chk = SqlHelper::insert(
$conn,
't_first_topup',
array(
'address' => $address,
'createtime' => myself()->_getNowTime(),
'status1' => 0,
'status2' => 0,
'status3' => 0,
)
);
if (!$chk) {
return;
}
}
private function lastInsertId($conn)
{
$row = $conn->execQueryOne('SELECT LAST_INSERT_ID() as lastId;', array());
return $row['lastId'];
}
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 countFreeBuyTimes($free_type, $id, $goods_id)
{
$conn = myself()->_getMysql('');
$account = myself()->_getAccountId();
switch ($free_type) {
case 1: {
$dayTime = myself()->_getNowDaySeconds();
$sql = 'SELECT COUNT(idx) as cnt FROM t_shop_free_record WHERE account_id = ? AND `id` = ? AND goods_id = ? AND createtime >= ?';
$row = $conn->execQueryOne($sql, array($account, $id, $goods_id, $dayTime));
return $row['cnt'];
}
break;
}
return 0;
}
private function addFreeBuyRecord($goods)
{
$conn = myself()->_getMysql('');
$account = myself()->_getAccountId();
switch ($goods['free_type']) {
case 1: {
$dayTime = myself()->_getNowTime();
SqlHelper::insert(
$conn,
't_shop_free_record',
array(
'account_id' => $account,
'shop_id' => $goods['shop_id'],
'id' => $goods['id'],
'goods_id' => $goods['goods_id'],
'goods_num' => $goods['goods_num'],
'free_type' => $goods['free_type'],
'free_num' => $goods['free_num'],
'createtime' => $dayTime,
)
);
}
break;
}
}
public function buyBlindBox()
{
$account = $this->_getAccountId();
$id = getReqVal('id', 0);
$num = getReqVal('num', 0);
if (!($num == 1 || $num == 10)) {
$this->_rspErr(2, 'num is invalid');
return;
}
$shop = mt\ShopGoods::get($id);
if (!$shop) {
$this->_rspErr(2, 'id is invalid');
return;
}
$meta = mt\Item::get($shop['goods_id']);
$cost = $shop['price'] * $num;
$isFreeBuy = false;
if (!empty($shop['free_type'])) {
$count = $this->countFreeBuyTimes($shop['free_type'], $shop['id'], $shop['goods_id']);
if ($count < $shop['free_num']) {
$isFreeBuy = true;
}
}
if ($isFreeBuy) {
if ($num != 1) {
$this->_rspErr(2, 'num is invalid');
return;
}
} else {
$costItems = $this->makeCostItems(V_ITEM_DIAMOND, $num * $shop['price']);
$lackItem = null;
if (!$this->_hasEnoughItems($costItems, $lackItem)) {
$this->_rspErr(2, $this->_getLackItemErrMsg($lackItem));
return;
}
}
$itemStore = mt\ShopChest::getRandomItemListByChestType($meta['sub_type']);
$grade = $meta['sub_type'];
$result = array();
for ($i = 0; $i < $num; $i++) {
$record = array();
foreach ($itemStore as $key => $value) {
$item = $this->weighted_random($value);
$itemMeta = mt\Item::get($item['item_id']);
if (!$itemMeta) {
$this->_rspErr(2, 'item_id is invalid ' . $item['item_id'] . ' in blind box ' . $shop['goods_id']);
return;
}
$propertyChgService = new services\PropertyChgService();
if ($item['item_type'] == 2) {
$this->internalAddItem($propertyChgService, $itemMeta, $item['num'], 0, $grade);
} else {
for ($j = 0; $j < $item['num']; $j++) {
$this->internalAddItem($propertyChgService, $itemMeta, 1, 0, $grade);
}
}
$record[$key] = array("item_id" => $item['item_id'], "item_num" => $item['num']);
array_push($result, $record[$key]);
}
if ($isFreeBuy) {
$this->addFreeBuyRecord($shop);
}
}
if (!$isFreeBuy) {
$this->_decItems($costItems);
$event = [
'name' => LogService::SHOP_BUY_ITEM_BLIND_BOX,
'val' => $costItems[0]['item_num']
];
LogService::consumeDiamond($event);
}
$propertyChgService->addUserChg();
$this->_rspData(
array(
'reuslt' => $result,
'property_chg' => $propertyChgService->toDto(),
)
);
}
}