From c4dc22055983d9a66412ed0eafa7928e33bf9d97 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 16:38:14 +0800 Subject: [PATCH 01/10] ... --- webapp/controller/ShopController.class.php | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 014ef306..2e267d20 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -812,6 +812,11 @@ class ShopController extends BaseAuthedController public function buyGoodsNormal() { + $address = $this->_getAddress(); + if (empty($address)) { + $this->_rspErr(2, 'address is empty'); + return; + } $id = getReqVal('id', 0); $token_type = getReqVal('token_type', ''); $goods_num = getReqVal('goods_num', 0); @@ -864,6 +869,7 @@ class ShopController extends BaseAuthedController } break; case ShopController::TOTAL_BUY_LIMIT: { + $sendingTimes = $this->countBuyGoodsRequestTimesByGoodsId($address, $row['goods_id']); $buyRecord = getXVal($buyRecordHash, $id); $boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1; if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $row['limit_num']) { @@ -899,6 +905,51 @@ class ShopController extends BaseAuthedController $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); + } + $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_CEG: case ShopController::TOKEN_TYPE_CEC: @@ -1145,6 +1196,20 @@ class ShopController extends BaseAuthedController } } + private function countBuyGoodsRequestTimesByGoodsId($address, $goodsId) + { + $self = myself(); + if (!$self) return; + + $conn = $self->_getMysql(''); + + $sql = "SELECT COUNT(*) AS cnt FROM t_bc_order WHERE address = '$address' AND item_id = '$goodsId'"; + + $row = $conn->execQuery($sql); + + return $row[0]['cnt']; + } + private function outsideBuy($shopId, $itemId, $itemNum, $costItemId) { $propertyChgService = new services\PropertyChgService(); From a95cebf7d6659ba2e4986089dd88a67c89be4451 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 16:42:44 +0800 Subject: [PATCH 02/10] ... --- webapp/services/callback/BuyShopGoodsCbService.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/webapp/services/callback/BuyShopGoodsCbService.php b/webapp/services/callback/BuyShopGoodsCbService.php index 289d8b1b..0b435797 100644 --- a/webapp/services/callback/BuyShopGoodsCbService.php +++ b/webapp/services/callback/BuyShopGoodsCbService.php @@ -4,11 +4,13 @@ namespace services; require_once('mt/Dailyselection.php'); +require_once('ShopAddItemService.php'); define('V_ORDER_TYPE_BUY_SHOP_GOODS', 1); use phpcommon\SqlHelper; use mt\Dailyselection; +use mt\Shop; class BuyShopGoodsCbService { @@ -91,6 +93,7 @@ class BuyShopGoodsCbService private function _addGoods($address, $goods) { - error_log("BuyShopGoodsCbService::_addGoods() address: $address, goods: " . json_encode($goods)); + $itemService = new ShopAddItemService(); + $itemService->addItem($address, $goods['goods_id'], $goods['goods_num']); } } From a3df8fba492560ee73c639dce98b3e76c48acc09 Mon Sep 17 00:00:00 2001 From: songliang Date: Tue, 20 Jun 2023 16:47:49 +0800 Subject: [PATCH 03/10] ... --- webapp/controller/ShopController.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 2e267d20..64b41750 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -869,7 +869,6 @@ class ShopController extends BaseAuthedController } break; case ShopController::TOTAL_BUY_LIMIT: { - $sendingTimes = $this->countBuyGoodsRequestTimesByGoodsId($address, $row['goods_id']); $buyRecord = getXVal($buyRecordHash, $id); $boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1; if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $row['limit_num']) { @@ -880,6 +879,11 @@ class ShopController extends BaseAuthedController $this->_rspErr(2, 'he maximum number of purchase restrictions has been reached'); return; } + $sendingTimes = $this->countBuyGoodsRequestTimesByGoodsId($address, $row['goods_id']); + if ($sendingTimes >= $row['limit_num']) { + $this->_rspErr(2, 'The maximum number of purchase restrictions has been reached'); + return; + } } break; default: { From 0ba8a1f2faf1f945e6a9ef8bbd6e585194dbac77 Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 11:32:36 +0800 Subject: [PATCH 04/10] ... --- doc/Shop.py | 18 ++++++ webapp/models/ShopBuyRecord.php | 62 +++++++++++++++++-- .../callback/BuyShopGoodsCbService.php | 7 ++- 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/doc/Shop.py b/doc/Shop.py index 7b36f76f..5d1b56bb 100644 --- a/doc/Shop.py +++ b/doc/Shop.py @@ -96,6 +96,24 @@ class Shop(object): ['goods_chg', _common.NewGoods(), '购买后更新商品的最新信息(可能为null客户端需要做容错处理)'], ] }, + { + 'name': 'buyGoodsNormal', + 'desc': '购买商品(正式)', + 'group': 'Shop', + 'url': 'webapp/index.php?c=Shop&a=buyGoodsNew', + 'params': [ + _common.ReqHead(), + ['id', 0, '商品唯一id,参见shopGoods表'], + ['token_type', '', "选用币种"], + ['goods_num', 0, '商品数量'], + ], + 'response': [ + _common.RspHead(), + ['award', _common.Award(), '奖励信息'], + ['property_chg', _common.PropertyChg(), '属性变更'], + ['goods_chg', _common.NewGoods(), '购买后更新商品的最新信息(可能为null客户端需要做容错处理)'], + ] + }, { 'name': 'buyGoodsDirect', 'desc': '直接购买(充值,gold)', diff --git a/webapp/models/ShopBuyRecord.php b/webapp/models/ShopBuyRecord.php index 843a4576..ce8e9598 100644 --- a/webapp/models/ShopBuyRecord.php +++ b/webapp/models/ShopBuyRecord.php @@ -5,7 +5,8 @@ namespace models; use mt; use phpcommon\SqlHelper; -class ShopBuyRecord extends BaseModel { +class ShopBuyRecord extends BaseModel +{ public static function find($itemId) { @@ -29,7 +30,7 @@ class ShopBuyRecord extends BaseModel { 'account_id' => myself()->_getAccountId(), ) ); - return array_map(function($row) { + return array_map(function ($row) { $nowDaySeconds = myself()->_getNowDaySeconds(); if (!($row['last_buy_time'] >= $nowDaySeconds && $row['last_buy_time'] <= $nowDaySeconds)) { $row['this_day_buy_times'] = 0; @@ -46,7 +47,7 @@ class ShopBuyRecord extends BaseModel { { $rows = self::all(); $buyRecordHash = array(); - array_walk($rows, function ($row) use(&$buyRecordHash) { + array_walk($rows, function ($row) use (&$buyRecordHash) { $buyRecordHash[$row['item_id']] = $row; }); return $buyRecordHash; @@ -54,8 +55,7 @@ class ShopBuyRecord extends BaseModel { public static function toDto($row) { - return array( - ); + return array(); } public static function add($itemId, $itemNum) @@ -97,4 +97,56 @@ class ShopBuyRecord extends BaseModel { ); } + public static function addWithAddress($address, $itemId, $itemNum) + { + $account_id = ShopBuyRecord::getAccountId($address); + SqlHelper::upsert( + myself()->_getMysql($address), + 't_shop_buy_record', + array( + 'account_id' => $account_id, + 'item_id' => $itemId, + ), + array( + 'this_day_buy_times' => function () { + $nowDaySeconds = myself()->_getNowDaySeconds(); + $cond = " last_buy_time>=${nowDaySeconds} AND last_buy_time<=${nowDaySeconds} + 3600 * 24 "; + return "CASE WHEN (${cond}) THEN this_day_buy_times + 1 ELSE 0 END"; + }, + 'this_week_buy_times' => function () { + $mondaySeconds = myself()->_getMondaySeconds(); + $cond = " last_buy_time>=${mondaySeconds} AND last_buy_time<=${mondaySeconds} + 3600 * 24 * 7 "; + return "CASE WHEN (${cond}) THEN this_week_buy_times + 1 ELSE 0 END"; + }, + 'total_buy_times' => function () { + return 'total_buy_times + 1'; + }, + 'last_buy_time' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowTime(), + ), + array( + 'account_id' => $account_id, + 'item_id' => $itemId, + 'this_day_buy_times' => 1, + 'this_week_buy_times' => 1, + 'total_buy_times' => 1, + 'last_buy_time' => myself()->_getNowTime(), + 'createtime' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowTime(), + ) + ); + } + + private static function getAccountId($address) + { + $row = SqlHelper::ormSelectOne( + myself()->_getMysql($address), + 't_user', + array( + 'address' => $address + ) + ); + + return $row['account_id']; + } } diff --git a/webapp/services/callback/BuyShopGoodsCbService.php b/webapp/services/callback/BuyShopGoodsCbService.php index 0b435797..37e31962 100644 --- a/webapp/services/callback/BuyShopGoodsCbService.php +++ b/webapp/services/callback/BuyShopGoodsCbService.php @@ -5,12 +5,14 @@ namespace services; require_once('mt/Dailyselection.php'); require_once('ShopAddItemService.php'); +require_once('models/ShopBuyRecord.php'); define('V_ORDER_TYPE_BUY_SHOP_GOODS', 1); use phpcommon\SqlHelper; use mt\Dailyselection; use mt\Shop; +use models\ShopBuyRecord; class BuyShopGoodsCbService { @@ -94,6 +96,9 @@ class BuyShopGoodsCbService private function _addGoods($address, $goods) { $itemService = new ShopAddItemService(); - $itemService->addItem($address, $goods['goods_id'], $goods['goods_num']); + $item_id = $goods['goods_id']; + $goods_num = $goods['goods_num']; + $itemService->addItem($address, $item_id, $goods_num); + ShopBuyRecord::addWithAddress($address, $item_id, $goods_num); } } From 0fcb61d9661bef22ac9cd2bad9f5445306eec29e Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 11:41:39 +0800 Subject: [PATCH 05/10] ... --- .../callback/BuyShopGoodsCbService.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/webapp/services/callback/BuyShopGoodsCbService.php b/webapp/services/callback/BuyShopGoodsCbService.php index 37e31962..213a9b83 100644 --- a/webapp/services/callback/BuyShopGoodsCbService.php +++ b/webapp/services/callback/BuyShopGoodsCbService.php @@ -43,14 +43,17 @@ class BuyShopGoodsCbService return; } + $order_id = $order['order_id']; $address = $order['address']; - $ext_data = $order['ext_data']; - $goods_id = $order['item_id']; - $goods_num = $order['item_num']; + // $ext_data = $order['ext_data']; + $item_id = $order['item_id']; + $item_num = $order['item_num']; + + error_log("callback buynormal address: $address, order_id: $order_id, goods_id: $item_id, goods_num: $item_num"); $this->_addGoods($address, array( - 'goods_id' => $goods_id, - 'goods_num' => $goods_num, + 'goods_id' => $item_id, + 'goods_num' => $item_num, )); } @@ -69,6 +72,8 @@ class BuyShopGoodsCbService $grid = $ext_data['grid']; $count = $ext_data['count']; + error_log("callback buyDailySelection address: $address, order_id: $order_id, item_id: $item_id, item_num: $item_num, idx: $idx, grid: $grid, count: $count"); + $conn = $self->_getMysql($address); $sql = "SELECT count_$grid FROM t_shop_dailyselection WHERE idx = $idx"; $chk = $conn->execQuery($sql); @@ -76,7 +81,7 @@ class BuyShopGoodsCbService return; } if ($chk[0]['count_' . $grid] < $count) { - error_log("BuyShopGoodsCbService::_buyDailySelection() count not enough, address: $address, order_id: $order_id, idx: $idx, grid: $grid, count: $count"); + error_log("BuyShopGoodsCbService::_buyDailySelection() count not enough, address: $address, order_id: $order_id, item_id: $item_id, item_num: $item_num, idx: $idx, grid: $grid, count: $count"); return; } @@ -89,7 +94,7 @@ class BuyShopGoodsCbService 'goods_num' => $item_num, )); } else { - error_log("BuyShopGoodsCbService::_buyDailySelection() decDailySelectionItem failed, address: $address, order_id: $order_id, idx: $idx, grid: $grid, count: $count"); + error_log("BuyShopGoodsCbService::_buyDailySelection() decDailySelectionItem failed, address: $address, order_id: $order_id, item_id: $item_id, item_num: $item_num, idx: $idx, grid: $grid, count: $count"); } } From 635aa9ef6953c88086587f1e513183419d210a95 Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 11:49:52 +0800 Subject: [PATCH 06/10] ... --- webapp/services/BlockChainService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/services/BlockChainService.php b/webapp/services/BlockChainService.php index 68bcefde..245d60ba 100644 --- a/webapp/services/BlockChainService.php +++ b/webapp/services/BlockChainService.php @@ -56,7 +56,7 @@ class BlockChainService { die(); return; } - error_log($response); + error_log("gameItemMallBuy:" . $response); $rspObj = json_decode($response, true); if ($rspObj['errcode'] == 0) { $transId = $rspObj['trans_id']; From 2e6b802b992b4b655c38273208e601ed746ada98 Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 13:43:46 +0800 Subject: [PATCH 07/10] .. --- doc/Shop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Shop.py b/doc/Shop.py index 5d1b56bb..69a736d3 100644 --- a/doc/Shop.py +++ b/doc/Shop.py @@ -100,7 +100,7 @@ class Shop(object): 'name': 'buyGoodsNormal', 'desc': '购买商品(正式)', 'group': 'Shop', - 'url': 'webapp/index.php?c=Shop&a=buyGoodsNew', + 'url': 'webapp/index.php?c=Shop&a=buyGoodsNormal', 'params': [ _common.ReqHead(), ['id', 0, '商品唯一id,参见shopGoods表'], From 96575205c7757ebe86a92967994ea5754da17e81 Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 13:57:35 +0800 Subject: [PATCH 08/10] ... --- doc/Shop.py | 3 +++ doc/_common.py | 7 +++++++ webapp/controller/ShopController.class.php | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/doc/Shop.py b/doc/Shop.py index 69a736d3..ad969dae 100644 --- a/doc/Shop.py +++ b/doc/Shop.py @@ -109,6 +109,9 @@ class Shop(object): ], 'response': [ _common.RspHead(), + ['ret', Union([ + [_common.ShopTrans(), '链上交易结果'], + ]), '购买结果'], ['award', _common.Award(), '奖励信息'], ['property_chg', _common.PropertyChg(), '属性变更'], ['goods_chg', _common.NewGoods(), '购买后更新商品的最新信息(可能为null客户端需要做容错处理)'], diff --git a/doc/_common.py b/doc/_common.py index ef261085..e1aac11e 100644 --- a/doc/_common.py +++ b/doc/_common.py @@ -1207,3 +1207,10 @@ class Sign(object): ['!award', [AwardItem()], '奖励信息'], ] +class ShopTrans(object): + + def __init__(self): + ['trans_id', '', 'trans_id'], + ['!params', [''], 'params'], + ['item_id', 0, 'item_id'], + ['item_num', 0, 'item_num'], \ No newline at end of file diff --git a/webapp/controller/ShopController.class.php b/webapp/controller/ShopController.class.php index 64b41750..99056526 100644 --- a/webapp/controller/ShopController.class.php +++ b/webapp/controller/ShopController.class.php @@ -977,7 +977,11 @@ class ShopController extends BaseAuthedController )), )); - $this->_rspOK(); + $response['item_id'] = $item_id; + $response['item_num'] = $item_count; + $this->_rspData( + $response + ); break; case ShopController::TOKEN_TYPE_BCEG: From 6de1c84b8efd8413c784833b12e40de2122b1b31 Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 13:58:12 +0800 Subject: [PATCH 09/10] ... --- doc/Shop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Shop.py b/doc/Shop.py index ad969dae..b94d0b26 100644 --- a/doc/Shop.py +++ b/doc/Shop.py @@ -109,7 +109,7 @@ class Shop(object): ], 'response': [ _common.RspHead(), - ['ret', Union([ + ['ret', _common.Union([ [_common.ShopTrans(), '链上交易结果'], ]), '购买结果'], ['award', _common.Award(), '奖励信息'], From afe1818fe876b74fb23cc13577bf374143635efd Mon Sep 17 00:00:00 2001 From: songliang Date: Wed, 21 Jun 2023 13:59:13 +0800 Subject: [PATCH 10/10] ... --- doc/_common.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/_common.py b/doc/_common.py index e1aac11e..bfe2cc1d 100644 --- a/doc/_common.py +++ b/doc/_common.py @@ -1210,7 +1210,9 @@ class Sign(object): class ShopTrans(object): def __init__(self): - ['trans_id', '', 'trans_id'], - ['!params', [''], 'params'], - ['item_id', 0, 'item_id'], - ['item_num', 0, 'item_num'], \ No newline at end of file + self.fields = [ + ['trans_id', '', 'trans_id'], + ['!params', [''], 'params'], + ['item_id', 0, 'item_id'], + ['item_num', 0, 'item_num'], + ] \ No newline at end of file