diff --git a/doc/_common.py b/doc/_common.py index e1d3586f..c65f6a64 100644 --- a/doc/_common.py +++ b/doc/_common.py @@ -1943,6 +1943,6 @@ class HashRateGoods(object): ['item_id', 0, '道具id'], ['item_num', 0, '道具数量'], ['purchased_num', 0, '已购买数量'], - ['stock_num', 0, '库存数量(-1不限购)'], + ['max_num', 0, '最大数量(-1不限购)'], ['count_down', 0, '倒计时(单位秒,只有已售罄才有效)'], ] diff --git a/sql/gamedb.sql b/sql/gamedb.sql index 39c00db2..76445206 100644 --- a/sql/gamedb.sql +++ b/sql/gamedb.sql @@ -2139,3 +2139,27 @@ CREATE TABLE `t_user_bind_gold_record` ( ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `t_hashrate_shop_buy_record` +-- + +DROP TABLE IF EXISTS `t_hashrate_shop_buy_record`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t_hashrate_shop_buy_record` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '账号id', + `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品id', + `item_id` int(11) NOT NULL DEFAULT '0' COMMENT '道具id', + `this_day_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '今日购买次数', + `this_week_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '本周购买次数', + `this_month_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '本月购买次数', + `total_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '总购买次数', + `last_buy_time` int(11) NOT NULL DEFAULT '0' COMMENT '最后一次购买时间', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + KEY `account_id` (`account_id`), + UNIQUE KEY `account_id_goods_id` (`account_id`, `goods_id`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; diff --git a/sql/gamedb2006_migrate_241001_01.sql b/sql/gamedb2006_migrate_241001_01.sql index a9d1b65d..9fffb4f0 100644 --- a/sql/gamedb2006_migrate_241001_01.sql +++ b/sql/gamedb2006_migrate_241001_01.sql @@ -14,6 +14,23 @@ CREATE TABLE `t_user_bind_gold_record` ( PRIMARY KEY (`idx`) ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +CREATE TABLE `t_hashrate_shop_buy_record` ( + `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', + `account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '账号id', + `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品id', + `item_id` int(11) NOT NULL DEFAULT '0' COMMENT '道具id', + `this_day_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '今日购买次数', + `this_week_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '本周购买次数', + `this_month_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '本月购买次数', + `total_buy_times` int(11) NOT NULL DEFAULT '0' COMMENT '总购买次数', + `last_buy_time` int(11) NOT NULL DEFAULT '0' COMMENT '最后一次购买时间', + `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', + `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', + PRIMARY KEY (`idx`), + KEY `account_id` (`account_id`), + UNIQUE KEY `account_id_goods_id` (`account_id`, `goods_id`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + insert into version (version) values(2024092401); commit; diff --git a/webapp/controller/BaseController.class.php b/webapp/controller/BaseController.class.php index 387e07fd..ec521724 100644 --- a/webapp/controller/BaseController.class.php +++ b/webapp/controller/BaseController.class.php @@ -88,6 +88,16 @@ class BaseController { return phpcommon\getMondaySeconds($time, $this->timeZone); } + public function _getMonthFirstDaySeconds() + { + return phpcommon\getThisMonthFirstDaySeconds($this->_getNowTime(), $this->timeZone); + } + + public function _getMonthFirstDaySecondsByTime($time) + { + return phpcommon\getThisMonthFirstDaySeconds($time, $this->timeZone); + } + public function _inTimeRangeStr($beginTimeStr, $endTimeStr) { $beginTimeOffset = myself()->_getDaySecondsOffset(strtotime("2024-6-22 ". $beginTimeStr)); diff --git a/webapp/controller/HashRateShopController.class.php b/webapp/controller/HashRateShopController.class.php index bcc2a856..5fdb4d98 100644 --- a/webapp/controller/HashRateShopController.class.php +++ b/webapp/controller/HashRateShopController.class.php @@ -1,12 +1,15 @@ internalBuyGoods(); + } + } + public function buyGoodsS() { + $this->internalBuyGoods(); + } + public function internalBuyGoods() + { + if (SERVER_ENV == _ONLINE) { + myself()->_verifySwitch('hashrate.shop.buy'); + } + $goodsId = getReqVal('goods_id', 0); + $goodsNum = intval(getReqVal('goods_num', 0)); + + if ($goodsNum < 1) { + myself()->_rspErr(1, "goods_num parameter error, goods_num: {$goodsNum}"); + return; + } + + $goodsMeta = mt\HashRateShop::find($goodsId); + if (!$goodsMeta) { + myself()->_rspErr(1, 'goods not found'); + return; + } + if ($goodsMeta['is_close']) { + myself()->_rspErr(1, 'no right to purchase'); + return; + } + $itemMeta = mt\Item::get($goodsMeta['item_id']); + if (!$itemMeta) { + myself()->_rspErr(1, 'goods not found, goods_id: ' . $goodsMeta['goods_id']); + return; + } + $errCode = 0; + $errMsg = ''; + if (!HashRateShopService::buyLimitCheck($goodsMeta, $goodsNum, $errCode, $errMsg)) { + myself()->_rspErr($errCode, $errMsg); + return; + } + $propertyChgService = new services\PropertyChgService(); + $awardService = new services\AwardService(); + $price = $goodsMeta['pile_price']; + if ($price < 1) { + myself()->_rspErr(1, "config error"); + return; + } + if ($price * $goodsNum < model\HashRate::getMyCurrentHashRate()) { + myself()->_rspErr(2, "hashrate not enough"); + return; + } + model\HashRate::decMyCurrentHashRate($price * $goodsNum); + HashRateShopBuyRecord::add($goodsMeta['goods_id'], $goodsNum, $goodsMeta['type']); + for ($i = 0; $i < $goodsNum; $i++) { + $this->internalAddItem($awardService, + $propertyChgService, + $itemMeta, + $goodsMeta['item_num'] + ); + } + $propertyChgService->addUserChg(); + $this->_rspData( + array( + 'award' => $awardService->toDto(), + 'property_chg' => $propertyChgService->toDto(), + ) + ); } } diff --git a/webapp/models/HashRate.php b/webapp/models/HashRate.php index 77255af3..61acb1dc 100644 --- a/webapp/models/HashRate.php +++ b/webapp/models/HashRate.php @@ -109,6 +109,44 @@ class HashRate extends BaseModel return $myHashRate; } + public static function getMyCurrentHashRate(){ + $currentPeriod = myself()->_callMtStatic('AchievementsCycle', 'getCurrentPeriod'); + if (empty($currentPeriod)) { + return 0; + } + $row = SqlHelper::ormSelectOne( + myself()->_getSelfMysql(), + 't_hash_rate_reward', + array( + 'account_id' => myself()->_getAccountId(), + 'period' => $currentPeriod['id'], + ) + ); + $myHashRate = 0; + if ($row){ + $myHashRate = $row['reward']; + } + return $myHashRate; + } + + public static function decMyCurrentHashRate($val){ + $val = intval($val); + $currentPeriod = myself()->_callMtStatic('AchievementsCycle', 'getCurrentPeriod'); + if ($currentPeriod) { + SqlHelper::update( + myself()->_getSelfMysql(), + 't_hash_rate_reward', + array( + 'account_id' => myself()->_getAccountId(), + 'period' => $currentPeriod['id'], + 'reward' => function () use($val) { + return "GREATEST(0, reward - ${val})"; + }, + ) + ); + } + } + public static function getTotalByAccount($accountId,$period){ $row = SqlHelper::ormSelectOne( myself()->_getSelfMysql(), @@ -126,4 +164,4 @@ class HashRate extends BaseModel } -} \ No newline at end of file +} diff --git a/webapp/models/HashRateShopBuyRecord.php b/webapp/models/HashRateShopBuyRecord.php new file mode 100644 index 00000000..b37dcbdb --- /dev/null +++ b/webapp/models/HashRateShopBuyRecord.php @@ -0,0 +1,107 @@ +_getSelfMysql(), + 't_hashrate_shop_buy_record', + array( + 'account_id' => myself()->_getAccountId(), + 'goods_id' => $goodsId, + ) + ); + return $row; + } + + public static function all() + { + $rows = SqlHelper::ormSelect( + myself()->_getSelfMysql(), + 't_hashrate_shop_buy_record', + array( + 'account_id' => myself()->_getAccountId(), + ) + ); + 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; + } + $mondaySeconds = myself()->_getMondaySeconds(); + if (!($row['last_buy_time'] >= $mondaySeconds && $row['last_buy_time'] <= $mondaySeconds)) { + $row['this_week_buy_times'] = 0; + } + $monthFirstDaySeconds = myself()->_getMonthFirstDaySeconds(); + if (!($row['last_buy_time'] >= $monthFirstDaySeconds && $row['last_buy_time'] <= $monthFirstDaySeconds)) { + $row['this_month_buy_times'] = 0; + } + return $row; + }, $rows); + } + + public static function allToHash() + { + $rows = self::all(); + $buyRecordHash = array(); + array_walk($rows, function ($row) use (&$buyRecordHash) { + $buyRecordHash[$row['goods_id']] = $row; + }); + return $buyRecordHash; + } + + public static function add($goodsId, $goodsNum, $itemId) + { + $goodsNum = intval($goodsNum); + SqlHelper::upsert( + myself()->_getSelfMysql(), + 't_hashrate_shop_buy_record', + array( + 'account_id' => myself()->_getAccountId(), + 'goods_id' => $goodsId, + ), + array( + 'this_day_buy_times' => function () use($goodsNum) { + $nowDaySeconds = myself()->_getNowDaySeconds(); + $cond = " last_buy_time>=${nowDaySeconds} AND last_buy_time<=${nowDaySeconds} + 3600 * 24 "; + return "CASE WHEN (${cond}) THEN this_day_buy_times + ${goodsNum} ELSE 0 END"; + }, + 'this_week_buy_times' => function () use($goodsNum) { + $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 + ${goodsNum} ELSE 0 END"; + }, + 'this_month_buy_times' => function () use($goodsNum) { + $monthFirstDaySeconds = myself()->_getMonthFirstDaySeconds(); + $cond = " last_buy_time>=${monthFirstDaySeconds} AND last_buy_time<=${monthFirstDaySeconds} + 3600 * 24 * 7 "; + return "CASE WHEN (${cond}) THEN this_month_buy_times + ${goodsNum} ELSE 0 END"; + }, + 'total_buy_times' => function () use($goodsNum) { + return 'total_buy_times + ${goodsNum}'; + }, + 'last_buy_time' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowTime(), + ), + array( + 'account_id' => myself()->_getAccountId(), + 'goods_id' => $goodsId, + 'item_id' => $itemId, + 'this_day_buy_times' => $goodsNum, + 'this_week_buy_times' => $goodsNum, + 'this_month_buy_times' => $goodsNum, + 'total_buy_times' => $goodsNum, + 'last_buy_time' => myself()->_getNowTime(), + 'createtime' => myself()->_getNowTime(), + 'modifytime' => myself()->_getNowTime(), + ) + ); + } + +} diff --git a/webapp/mt/HashRateShop.php b/webapp/mt/HashRateShop.php index 6542405c..6a58edba 100644 --- a/webapp/mt/HashRateShop.php +++ b/webapp/mt/HashRateShop.php @@ -6,6 +6,11 @@ use phpcommon; class HashRateShop { + const TOTAL_BUY_LIMIT = 0; + const DAILY_BUY_LIMIT = 1; + const WEEKLY_BUY_LIMIT = 2; + const MONTH_BUY_LIMIT = 3; + public static function find($id){ return getXVal(self::getMetaList(), $id, null); } @@ -18,6 +23,11 @@ class HashRateShop { return self::$metaList; } + public static function all() + { + return self::getMetaList(); + } + protected static $metaList; } diff --git a/webapp/services/HashRateShopService.php b/webapp/services/HashRateShopService.php index 5dbf6a14..55e8395b 100644 --- a/webapp/services/HashRateShopService.php +++ b/webapp/services/HashRateShopService.php @@ -2,34 +2,22 @@ namespace services; -require_once('mt/ShopGoods.php'); -require_once('mt/Item.php'); -require_once('mt/Shop.php'); +require_once('models/HashRateShopBuyRecord.php'); -require_once('models/ShopBuyRecord.php'); -require_once('models/Hero.php'); -require_once('models/HeroSkin.php'); -require_once('models/GunSkin.php'); +require_once('mt/HashRateShop.php'); +require_once('mt/Item.php'); use mt; use phpcommon; -use models\ShopBuyRecord; -use models\Hero; -use models\HeroSkin; -use models\GunSkin; + +use models\HashRateShopBuyRecord; class HashRateShopService { - public static function getGoodsList($shopId) + public static function getGoodsList() { - if ($shopId == 0) { - $goodsMetaList = mt\ShopGoods::all(); - } else { - $goodsMetaList = mt\ShopGoods::getGoodsList($shopId); - } - - $goodsMetaList = $goodsMetaList ? $goodsMetaList : array(); - $buyRecordHash = ShopBuyRecord::allToHash(); + $goodsMetaList = mt\HashRateShop::all(); + $buyRecordHash = HashRateShopBuyRecord::allToHash(); $goodsList = array(); foreach ($goodsMetaList as $goodsMeta) { @@ -37,121 +25,104 @@ class HashRateShopService { continue; } $goodsDto = array( - 'goods_id' => $goodsMeta['goods_id'], - 'goods_meta' => self::goodsMetaToInfo($goodsMeta), - 'bought_times' => 0, - 'free_num' => 0, + 'goods_id' => $goodsMeta['id'], + 'price' => $goodsMeta['pile_price'], + 'item_id' => $goodsMeta['type'], + 'item_num' => $goodsMeta['item_num'], + 'purchased_num' => 0, + 'max_num' => $goodsMeta['limit_num'], + 'count_down' => 0, ); array_push($goodsList, $goodsDto); switch ($goodsMeta['limit_type']) { - case mt\Shop::DAILY_BUY_LIMIT: { - $buyRecord = getXVal($buyRecordHash, $goodsMeta['goods_id']); - $goodsDto['bought_times'] = $buyRecord ? $buyRecord['this_day_buy_times'] : 0; + case mt\HashRateShop::DAILY_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $goodsMeta['id']); + $goodsDto['purchased_num'] = $buyRecord ? $buyRecord['this_day_buy_times'] : 0; } - break; - case mt\Shop::WEEKLY_BUY_LIMIT: { - $buyRecord = getXVal($buyRecordHash, $goodsMeta['goods_id']); - $goodsDto['bought_times'] = $buyRecord ? $buyRecord['this_week_buy_times'] : 0; + break; + case mt\HashRateShop::WEEKLY_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $goodsMeta['id']); + $goodsDto['purchased_num'] = $buyRecord ? $buyRecord['this_week_buy_times'] : 0; } - break; - case mt\Shop::TOTAL_BUY_LIMIT: { - $buyRecord = getXVal($buyRecordHash, $goodsMeta['goods_id']); - $goodsDto['bought_times'] = $buyRecord ? $buyRecord['total_buy_times'] : 0; + break; + case mt\HashRateShop::MONTH_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $goodsMeta['id']); + $goodsDto['purchased_num'] = $buyRecord ? $buyRecord['this_week_buy_times'] : 0; } - break; + break; + case mt\HashRateShop::TOTAL_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $goodsMeta['id']); + $goodsDto['purchased_num'] = $buyRecord ? $buyRecord['total_buy_times'] : 0; + } + break; default: { } - break; - } - - $itemMeta = mt\Item::get($goodsMeta['item_id']); - if ($itemMeta) { - /* - // 如果是皮肤,判断是否已经拥有,如果已经拥有,不能购买 - if ($itemMeta['type'] == mt\Item::HERO_SKIN_TYPE) { - $errCode = 0; - $errMsg = ''; - if (!self::canBuy($itemMeta, $errCode, $errMsg)) { - $goods['bought_times'] = 1; - } else { - $goods['bought_times'] = 0; - } - }*/ - } else if ($goodsMeta['goods_id'] != 9999){ - error_log('item not found:' . json_encode($goodsMeta)); + break; } } return $goodsList; } - public static function buyLimitCheck($goodsMeta, &$errCode, &$errMsg) + public static function buyLimitCheck($goodsMeta, $goodsNum, &$errCode, &$errMsg) { + if ($goodsMeta['is_close']) { + $errCode = 1; + $errMsg = 'cant buy'; + return; + } $errCode = 0; $errMsg = ''; - $buyRecordHash = ShopBuyRecord::allToHash(); + $buyRecordHash = HashRateShopBuyRecord::allToHash(); $boughtTimes = 1; $goodsId = $goodsMeta['goods_id']; { switch ($goodsMeta['limit_type']) { - case mt\Shop::DAILY_BUY_LIMIT: { + case mt\HashRateShop::DAILY_BUY_LIMIT: { $buyRecord = getXVal($buyRecordHash, $goodsId); - $boughtTimes = $buyRecord ? $buyRecord['this_day_buy_times'] + 1 : 1; + $boughtTimes = $buyRecord ? $buyRecord['this_day_buy_times'] + $goodsNum : 1; if ($buyRecord && getXVal($buyRecord, 'this_day_buy_times', 0) >= $goodsMeta['limit_num']) { $errCode = 2; $errMsg = 'Daily purchase limit'; return false; } } - break; - case mt\Shop::WEEKLY_BUY_LIMIT: { + break; + case mt\HashRateShop::WEEKLY_BUY_LIMIT: { $buyRecord = getXVal($buyRecordHash, $goodsId); - $boughtTimes = $buyRecord ? $buyRecord['this_week_buy_times'] + 1 : 1; + $boughtTimes = $buyRecord ? $buyRecord['this_week_buy_times'] + $goodsNum : 1; if ($buyRecord && getXVal($buyRecord, 'this_week_buy_times', 0) >= $goodsMeta['limit_num']) { $errCode = 2; $errMsg = 'Weekly purchase limit reached'; return false; } } - break; - case mt\Shop::TOTAL_BUY_LIMIT: { - // error_log("total buy limit " . $address . " " . $goodsId . " " . $goodsMeta['limit_num']); + break; + case mt\HashRateShop::MONTH_BUY_LIMIT: { $buyRecord = getXVal($buyRecordHash, $goodsId); - $boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + 1 : 1; + $boughtTimes = $buyRecord ? $buyRecord['this_month_buy_times'] + $goodsNum : 1; + if ($buyRecord && getXVal($buyRecord, 'this_month_buy_times', 0) >= $goodsMeta['limit_num']) { + $errCode = 2; + $errMsg = 'Month purchase limit reached'; + return false; + } + } + break; + case mt\HashRateShop::TOTAL_BUY_LIMIT: { + $buyRecord = getXVal($buyRecordHash, $goodsId); + $boughtTimes = $buyRecord ? $buyRecord['total_buy_times'] + $goodsNum : 1; if ($buyRecord && getXVal($buyRecord, 'total_buy_times', 0) >= $goodsMeta['limit_num']) { $errCode = 2; $errMsg = 'Purchase limit reached'; return false; } } - break; + break; default: { } - break; + break; } } return true; } - public static function goodsMetaToInfo($goodsMeta) - { - return array( - 'item_id' => $goodsMeta['item_id'], - 'item_num' => $goodsMeta['item_num'], - 'max_amount' => $goodsMeta['max_amount'], - 'shop_id' => $goodsMeta['shop_id'], - 'shopstage' => $goodsMeta['shopstage'], - 'tag' => $goodsMeta['tag'], - 'recommend' => $goodsMeta['recommend'], - 'token_type' => $goodsMeta['token_type'], - 'price' => $goodsMeta['price'], - 'free_type' => $goodsMeta['free_type'], - 'shop_icon' => $goodsMeta['shop_icon'], - 'gg_product_id' => $goodsMeta['gg_product_id'], - 'ios_product_id' => $goodsMeta['ios_product_id'], - 'bonus' => $goodsMeta['bonus'], - 'bonus_num' => $goodsMeta['bonus_num'], - 'function' => $goodsMeta['function'], - ); - } - }