* 6.0.0 第六版: 引入currency字段, 增加出海结算支持. 2022.11
* 5.0.0 第五版: 全部动态交易数据存入mysql. 2021.11
* 4.0.0 第四版: 言灵世界 商城模块. 2020.08
* 2.2.0 第三版: 独立的游戏币<元宝>, 面向多渠道的充值模式, 拉起充值成功后, 给玩家发放元宝. 游戏内部消费元宝,钻石和金币.可以用元宝购买金币和钻石.这一版在上面的PayProc中 * 2015年9月23日
* 2.1.0 mn_pay mn_AddUserCash ... 以 mn_ 打头的函数是第二版, 修改为伪托管模式,除了充值的时候跟腾讯通讯,其余时间自己管理游戏币:钻石. * 2015年7月23日
* 2.0.1 m_pay m_AddUserCash ... 以 m_ 打头的函数是第一版, 完全按照应用宝官方要求托管游戏币的模式开发的. * 2015年4月23日
* 1.0.0 Created at 2016-4-20. by --gwang
* @author gwang (mail@wanggangzero.cn)
* @copyright © 2016-4-20, SJZ LoyalSoft Corporation & gwang. All rights reserved.
*/
class PayProc {
const orderTab = 'tpl_order_tab';
/**
* 逻辑分发
* 所有的Proc中必须有这样一个方法
*/
public static function procMain() {
switch (req()->cmd) {
// 支付相关的活动
case CmdCode::cmd_pay_getfirstpaygift: # 8802 领取首充礼包
return PayProc::m_GetFirstPayGift();
// 游戏内二级货币消费
case CmdCode::cmd_mpay_pay: # 8807 消费..
return self::m_pay(); # ::==> 购买普通商城物品
case CmdCode::cmd_mpay_buyDynamic: # 8809 购买动态商城物品
return self::m_pay_buyDynamic();
case CmdCode::cmd_mpay_getDynamic: # 8810 刷新神秘商城物品
return self::m_pay_getDynamic();
// 充值消费
case CmdCode::cmd_mpay_get_balance: # 8808 刷新账号余额
return self::m_refreshChargeOrders(); # ::==> 刷新订单-领取充值金额
case CmdCode::cmd_mpay_selfCheckOrders: # 8811 自助检查异常订单
return self::selfhelpCheckOrders();
case CmdCode::cmd_mpay_getPayRecords: # 8812 查询订单记录
return self::GetPayRecoreds();
case CmdCode::cmd_mpay_PayDeliverGoods: # 8813 查询订单并发货
return self::PayDeliverGoods();
case CmdCode::cmd_mpay_UserRechargeDrawPrize: # 8814 充值领奖励 2022.10
return self::UserRechargeDrawPrize();
case CmdCode::cmd_mpay_NewFirstRecharge: # 8815 新首充功能 2022.10
return self::NewFirstRecharge();
default:
return Resp::err(ErrCode::cmd_err);
}
}
static $retArr;
/**
* 8815 新首冲功能5点前不能领取奖励,则该请求只是为了首充开发界面时获得最新时间戳
*/
static function NewFirstRecharge() {
UserProc::updateUserInfo();
return Resp::ok(array(
"ret" => 'true',
));
}
/**
* [8814]领取奖励 (新版2021)
*/
static function UserRechargeDrawPrize() {
list($type, $typeId) = req()->paras;
$user = ctx();
self::$retArr = array();
switch ($type) {
case Enum_Recharge::FirstRecharge://首冲
my_Assert($user->pay->firstRechage == 0, ErrCode::shop_firstRechargeNotRepeat);
StoreProc::AddMultiItemInStore(GameConfig::globalsettings()->firstRechargePrizes);
$user->pay->firstRechage = 1;
self::$retArr[] = GameConfig::globalsettings()->firstRechargePrizes;
break;
case Enum_Recharge::DaliySpecialPackages://每日特惠
my_Assert(!in_array($typeId, $user->shopdata->daliySpecialPackages), ErrCode::shop_daliySpecialRewardNotRepeat);
$mo = GameConfig::shop_limit_getItem($typeId);
my_Assert($mo != null, ErrCode::err_const_no);
if ($mo->price != 0) {//购买60元7天特惠,则不是免费的礼包现在也可以领取。这里校验一下
//my_Assert($user->shopdata->daliySpecial_ts!= 0, ErrCode::shop_daliySpecialRewardNotRepeat);
$ts = $user->shopdata->daliySpecial_ts + 7 * 24 * 60 * 60;
my_Assert(now() < $ts, ErrCode::shop_daliySpecialRewardNotRepeat);
}
$itemid = explode(',', $mo->reward)[0];
$itemMO = GameConfig::item_package_getItem($itemid);
my_Assert(null != $itemMO, ErrCode::err_const_no);
StoreProc::AddMultiItemInStore($itemMO->contents);
self::$retArr[] = $itemMO->contents;
$shopdata = new Info_UserShop(ctx()->shopdata);
$shopdata->daliySpecialPackages[] = $typeId;
ctx()->shopdata = $shopdata;
break;
case Enum_Recharge::RechargeRebate://充值返利
$mo = GameConfig::rechargeRebate_getItem(3, $typeId);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert($user->baseInfo->charge_amt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
my_Assert(!in_array($typeId, $user->shopdata->rechargeRebateRewardsList), ErrCode::shop_RechargeRebateRewardNotRepeat);
StoreProc::AddMultiItemInStore($mo->rewards);
self::$retArr[] = $mo->rewards;
break;
case Enum_Recharge::LimitBuy://限购中免费礼包领取
$packageCfg = GameConfig::shop_limit_getItem($typeId);
my_Assert(null != $packageCfg, ErrCode::err_const_no);
my_Assert($packageCfg->price == 0, ErrCode::shop_limit_NotFree);
self::checklimitBuyRecharge($typeId);
break;
case Enum_Recharge::Accumulate: # 累充, gwang 2022.10.18
// list($amount, $day) = explode('-', $typeId); # 拆分key1,key2
// $cfg = GameConfig::shop_accumulating_getItem($amount, $day); # 配置对象
// my_Assert(null != $cfg, ErrCode::err_const_no); # 防御null
//
// $acc = new Ins_Accumulate($user->shopdata->shopAccumulateData); # 累充对象
// my_Assert(!$acc->IsDrawed($amount, $day), ErrCode::active_hasgetted); # 防御: 已经领取
// my_Assert($user->baseInfo->rechargeFun_amt >= $cfg->amount, "累充金额不足!"); # 校验: 金额
// my_Assert($acc->EndDay() >= tsDay(), "领取时间已过!"); # 校验: 时间
// StoreProc::AddMultiItemInStore($cfg->goods); # 发放奖品
// $user->shopdata->shopAccumulateData = $acc->SetDrawd($amount, $day); # 更新数据
// self::$retArr[] = $cfg->goods;
$mo = GameConfig::rechargeRebate_getItem(Enum_Recharge::Accumulate, $typeId);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert($user->baseInfo->charge_amt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
my_Assert(!in_array($typeId, $user->shopdata->rechargeRebateRewardsList), ErrCode::shop_RechargeRebateRewardNotRepeat);
$user->shopdata->rechargeRebateRewardsList[] = $typeId;
StoreProc::AddMultiItemInStore($mo->rewards);
self::$retArr[] = $mo->rewards;
break;
case Enum_Recharge::FirstRecharge_new:
$mo = GameConfig::shop_accumulating_getItem($typeId);
my_Assert(null != $mo, ErrCode::err_const_no);
$shopdata = new Info_UserShop(ctx()->shopdata);
$amount = $mo->amount;
if (!StlUtil::dictHasProperty($shopdata->fRechargeRecord, $amount)) {
$shopdata->fRechargeRecord->$amount = array();
}
my_Assert(!in_array($typeId, $shopdata->fRechargeRecord->$amount), ErrCode::active_FirstRechargeRewardRepeat);
$shopdata->fRechargeRecord->$amount[] = $typeId;
StoreProc::AddMultiItemInStore($mo->goods); # 发放奖品
ctx()->shopdata = $shopdata;
self::$retArr[] = $mo->goods;
break;
case Enum_Recharge::DayAccumulateRecharge: #每周累计金额奖励
$mo = GameConfig::rechargeRebate_getItem($type, $typeId);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert($user->shopdata->dayRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
my_Assert(!in_array($typeId, $user->shopdata->dayRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat);
$user->shopdata->dayRechargeReceived[] = $typeId;
// if ($rechargeType == 1) {
// my_Assert($user->shopdata->dayRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
// my_Assert(!in_array($rmb, $user->shopdata->dayRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat);
// $user->shopdata->dayRechargeReceived[] = $rmb;
// } else if($rechargeType == 2){
// my_Assert($user->shopdata->weekRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
// my_Assert(!in_array($rmb, $user->shopdata->weekRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat);
// $user->shopdata->weekRechargeReceived[] = $rmb;
// }
StoreProc::AddMultiItemInStore($mo->rewards);
self::$retArr[] = $mo->rewards;
break;
case Enum_Recharge::WeekAccumulateRecharge: #每周累计金额奖励
$mo = GameConfig::rechargeRebate_getItem($type, $typeId);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert($user->shopdata->weekRechargeAmt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
my_Assert(!in_array($typeId, $user->shopdata->weekRechargeReceived), ErrCode::shop_RechargeRebateRewardNotRepeat);
$user->shopdata->weekRechargeReceived[] = $typeId;
StoreProc::AddMultiItemInStore($mo->rewards);
self::$retArr[] = $mo->rewards;
break;
default:
break;
}
ctx($user);
UserProc::updateUserInfo();
return Resp::ok(array(
"ret" => self::$retArr,
"pay" => $user->pay,
"shopdata" => ctx()->shopdata,
"base" => $user->baseInfo,
"store" => $user->store,
));
}
/**
* 限购礼包--终身礼包--套装礼包--校验
* @param type $packageId
*/
private static function checklimitBuyRecharge($packageId) { # 参数; 礼包id
$shopdata = new Info_UserShop(ctx()->shopdata);
$packageCfg = GameConfig::shop_limit_getItem($packageId);
my_Assert(null != $packageCfg, ErrCode::err_const_no);
$arr = array();
if ($packageCfg->goodsType == Enum_Recharge::LifelongGift) {
$shopdata->lifelongGiftReceived[] = $packageId;
$arr = $shopdata->lifelongGiftReceived;
} elseif ($packageCfg->goodsType == Enum_Recharge::SuitGift) {
$ts = now() - $shopdata->suitGiftStartTs;
my_Assert($ts <= $packageCfg->limit_ts, ErrCode::shop_limit_TsMax); # 校验时间
$shopdata->suitGiftReceived[] = $packageId;
$arr = $shopdata->suitGiftReceived;
} else {
switch ((int) $packageCfg->subType) {
case 1:
$shopdata->purchasedDailyLimitPackages[] = $packageId;
$arr = $shopdata->purchasedDailyLimitPackages;
break;
case 2:
$shopdata->purchasedWeeklyLimitPackages[] = $packageId;
$arr = $shopdata->purchasedWeeklyLimitPackages;
break;
case 3:
$shopdata->purchasedMonthlyLimitPackages[] = $packageId;
$arr = $shopdata->purchasedMonthlyLimitPackages;
break;
default:
Err(ErrCode::err_innerfault);
}
}
$hasN = count(array_filter($arr, function ($val)use ($packageId) { # 计数:筛选条件
return $val == $packageId;
}));
my_Assert($hasN <= $packageCfg->limit_num, ErrCode::shop_limit_max); # 校验购买数量
$itemid = explode(',', $packageCfg->reward)[0]; # 奖励礼包Id
$itemMO = GameConfig::item_package_getItem($itemid);
my_Assert(null != $itemMO, ErrCode::err_const_no);
$err = StoreProc::AddMultiItemInStore($itemMO->contents); # 发放奖励
self::$retArr[] = $itemMO->contents;
my_Assert(ErrCode::ok == $err, $err);
ctx()->shopdata = $shopdata; # 回写数据
}
/**
* [8813] 充值发货 (新版2021)
*/
static function PayDeliverGoods() {
list($cpOrderId) = req()->paras;
$result = pay_op::CheckAndDrawOrder(req()->uid, $cpOrderId, array(new PayProc, 'distributePayGoods'));
my_Assert($result->err == 0, ErrCode::pay_fail);
$user = ctx();
NormalEventProc::OnPaySuccess();
UserProc::updateUserInfo(); # 回写玩家数据
return Resp::ok(array(
"ret" => self::$retArr,
"pay" => $user->pay,
"base" => $user->baseInfo,
"shopdata" => $user->shopdata,
"store" => $user->store,
));
}
//发货
static function distributePayGoods($order = null) {
my_Assert($order->product_id != null, ErrCode::pay_order_product_id);
$user = ctx();
self::$retArr = array();
if ($order->product_id >= 6 && $order->product_id <= 1000) {//充值表
$mo = GameConfig::recharge_getItem($order->product_id);
my_Assert($mo != null, ErrCode::err_const_no);
if (!StlUtil::dictHasProperty($user->shopdata, 'rechargeRecordList')) {
$user->shopdata->rechargeRecordList = array();
}
$cash = $mo->rmd * 10;
if (!in_array($order->product_id, $user->shopdata->rechargeRecordList)) {
$cash = $mo->rmd * 10 * $mo->firstDouble;
$user->shopdata->rechargeRecordList[] = $order->product_id;
}
$user->base()->Add_Cash($cash);
self::$retArr[] = "2," . $cash;
} elseif ($order->product_id >= 801001 && $order->product_id <= 803999) {//限购
self::checklimitBuyRecharge($order->product_id);
$mo = GameConfig::shop_limit_getItem($order->product_id);
if ($mo->subType == 1) {
$user->shopdata->dayRechargeAmt += $order->amount;
} else if ($mo->subType == 2) {
$user->shopdata->weekRechargeAmt += $order->amount;
}
} elseif ($order->product_id >= 804001 && $order->product_id <= 804999) {//每日特惠
$mo = GameConfig::shop_limit_getItem($order->product_id);
my_Assert($mo != null, ErrCode::err_const_no);
if ($mo->price == 60) {
$user->shopdata->daliySpecial_ts = now();
} else {
$itemid = explode(',', $mo->reward)[0];
$itemMO = GameConfig::item_package_getItem($itemid);
my_Assert(null != $itemMO, ErrCode::err_const_no);
StoreProc::AddMultiItemInStore($itemMO->contents);
$user->shopdata->daliySpecialPackages[] = $mo->typeId;
self::$retArr[] = $itemMO->contents;
}
} elseif ($order->product_id >= 805001 && $order->product_id <= 805999) {//限时
$mo = GameConfig::shop_limit_getItem($order->product_id);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert(!in_array($order->product_id, $user->shopdata->limitTsActiveRewardsList), ErrCode::err_const_no);
$user->shopdata->limitTsActiveRewardsList[] = $mo->typeId;
$itemid = explode(',', $mo->reward)[0];
$itemMO = GameConfig::item_package_getItem($itemid);
my_Assert(null != $itemMO, ErrCode::err_const_no);
StoreProc::AddMultiItemInStore($itemMO->contents); //领取奖励
self::$retArr[] = $itemMO->contents;
} elseif ($order->product_id >= 806001 && $order->product_id <= 806999) {//首充【2022-10-19新的首充功能】
$mo = GameConfig::shop_accumulating_getItem($order->product_id);
my_Assert($mo != null, ErrCode::err_const_no);
$shopdata = new Info_UserShop(ctx()->shopdata);
$amount = $mo->amount;
if (!StlUtil::dictHasProperty($shopdata->fRechargeTime, $amount)) {
$shopdata->fRechargeTime->$amount = TimeUtil::tsDay();
}
$cost = 0;
$dic = GameConfig::shop_accumulating();
foreach ($dic as $k => $item) {
if ($cost <= $item->amount) {
$cost = $item->amount;
}
}
if ($cost <= $amount && $shopdata->suitGiftStartTs == 0) {
$shopdata->suitGiftStartTs = now();
}
ctx()->shopdata = $shopdata;
//self::$retArr[] = $mo->goods;
} elseif ($order->product_id >= 807001 && $order->product_id <= 807999) {//终身礼包
self::checklimitBuyRecharge($order->product_id);
} elseif ($order->product_id >= 808001 && $order->product_id <= 808999) {//套装礼包
self::checklimitBuyRecharge($order->product_id);
} elseif ($order->product_id >= 901001 && $order->product_id <= 999999) {//月卡
$shopdata = new Info_UserShop(ctx()->shopdata);
$packageCfg = GameConfig::shop_monthVIP_getItem($order->product_id);
my_Assert(null != $packageCfg, ErrCode::err_const_no);
if ($packageCfg->subType == 4) {
my_Assert($shopdata->monthlyVIP1_ts + $packageCfg->ExpireTs * 3600 * 24 < now(), ErrCode::shop_monthlyvip_buyed);
} elseif ($packageCfg->subType == 5) {
my_Assert($shopdata->monthlyVIP2_ts + $packageCfg->ExpireTs * 3600 * 24 < now(), ErrCode::shop_monthlyvip_buyed);
}
$err = StoreProc::AddMultiItemInStore($packageCfg->pri_reward); # 发放一次性奖励
self::$retArr[] = $packageCfg->pri_reward;
my_Assert(ErrCode::ok == $err, $err);
if ($packageCfg->subType == 4) {
$shopdata->monthlyVIP1_ts = 3600 * 24 * (totalDays() + 1) - 1;
} elseif ($packageCfg->subType == 5) {
$shopdata->monthlyVIP2_ts = 3600 * 24 * (totalDays() + 1) - 1;
}
EmailProc::SendMonthlyVIPDailyReward(req()->zoneid, req()->uid, $packageCfg->name, $packageCfg->daily_reward);
ctx()->shopdata = $shopdata;
}
$user->baseInfo->charge_amt += $order->amount;
ctx($user);
return true;
}
static function suitGiftCheck() {
$shopdata = new Info_UserShop(ctx()->shopdata);
$cost = 0;
$dic = GameConfig::shop_accumulating();
foreach ($dic as $k => $item) {
if ($cost <= $item->amount) {
$cost = $item->amount;
}
}
if (StlUtil::dictHasProperty($shopdata->fRechargeTime, $cost)) {
if ($shopdata->suitGiftStartTs == 0) {
$shopdata->suitGiftStartTs = now();
}
} else {
$shopdata->suitGiftStartTs = 0;
}
ctx()->shopdata = $shopdata;
}
static function checkAmount($order) {
my_Assert($order->product_id != null, ErrCode::pay_order_product_id);
if ($order->product_id >= 6 && $order->product_id <= 1000) {//充值表
$mo = GameConfig::recharge_getItem($order->product_id);
my_Assert($mo != null, ErrCode::err_const_no);
my_Assert($order->amount == $mo->rmd, ErrCode::pay_price_err);
} elseif ($order->product_id >= 801001 && $order->product_id <= 801999) {//限购
//该功能暂时没有开发
} elseif ($order->product_id >= 804001 && $order->product_id <= 804999) {//每日特惠
$mo = GameConfig::shop_limit_getItem($order->product_id);
my_Assert($mo->price == $order->amount, ErrCode::pay_price_err);
} elseif ($order->product_id >= 805001 && $order->product_id <= 805999) {//限时
//该功能暂时没有开发
} elseif ($order->product_id >= 901001 && $order->product_id <= 999999) {//月卡
$packageCfg = GameConfig::shop_monthVIP_getItem($order->product_id);
my_Assert(null != $packageCfg, ErrCode::err_const_no);
my_Assert($packageCfg->price == $order->amount, ErrCode::pay_price_err);
}
return true;
}
/**
* 礼包有了的第一次登录记录
*/
static function SuitGiftTsRecord() {
$shopdata = new Info_UserShop(ctx()->shopdata);
if (!StlUtil::dictHasProperty($shopdata, 'suitGiftStartTs')) {
$shopdata->suitGiftStartTs = 0;
}
if ($shopdata->suitGiftStartTs == 0) {
$shopdata->suitGiftStartTs = now();
}
ctx()->shopdata = $shopdata;
}
/**
* 8812 查询充值记录
*/
static function GetPayRecoreds() {
$uid = req()->uid;
$table = "tpl_order_tab";
$arr = daoInst()->select(" cpOrderId as '订单' ,product_name as '道具',amount as '金额' ,from_unixtime(order_ts) as '时间' ")->from($table)
->where("uid")->eq($uid)
->andWhere("status")->eq(1)
->fetchall();
return Resp::ok($arr);
}
//
//
/**
* 刷新充值订单(领取充值结果)
*/
public static function m_refreshChargeOrders() {
# 客户端参数解析
$uid = req()->uid; # userID
$zoneid = req()->zoneid; # 分区Id
if (count(req()->paras) <= 0) { # 参数为空, 执行自检逻辑
return self::selfhelpCheckOrders();
}
$cpOrderId = req()->paras[0]; # 后台订单编号
if (!$uid || ($zoneid < 1) || strlen($cpOrderId) != 16) { # 订单编号长16位
return Resp::err(ErrCode::paras_err);
}
$order = daoInst()->select()->from(self::orderTab) # 取订单数据
->where('cpOrderId')->eq($cpOrderId)
->limit(1)->fetch();
if (!$order) {
// var_dump($order);
CLog::pay(' 订单不存在! ' . $cpOrderId);
return Resp::err(ErrCode::pay_order_no);
}
if (false === strpos($uid, $order->uid)) { # UID不符
return Resp::err(ErrCode::pay_order_uid);
}
if ($order->status != 1) {
CLog::pay(' 订单尚未完成支付!');
return Resp::err(ErrCode::pay_order_paystatus);
}
if ($order->drawed_ts > 0) { # 定单已经发过货了
CLog::pay(' 订单重复请求发货!' . $cpOrderId);
return Resp::err(ErrCode::pay_order_drawed);
}
// 准备发货
$product_id = $order->product_id;
$product_count = $order->product_count;
$typid = substr("$product_id", 0, 3); # 提取商品编号前缀
switch ($typid) {
case '802': # 神秘商城物品
$item = GameConfig::secretshop_typeId_getItem($product_id);
break;
case '801': # 商城物品
$item = GameConfig::shop_getItem($product_id);
break;
default :
return Resp::err(ErrCode::pay_systembusy_err);
}
my_Assert(isset($item), ErrCode::pay_shopItem_cosnt_goods_err);
if ($item->pricetype != 0) {
CLog::pay(" 道具付费类型异常:" . $product_id);
return Resp::err(ErrCode::pay_m_type_err);
}
for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况
StoreProc::AddMultiItemInStore($item->goods, 5); # 发货
}
$n = daoInst()->update(self::orderTab)
->data(array('drawed_ts' => now()))
->where('cpOrderId')->eq($cpOrderId)
->exec();
my_Assert($n > 0, ErrCode::err_db); # 数据库操作失败
ctx()->baseInfo->charge_amt += $order->amount; # 历史充值记录(单位分)
UserProc::updateUserInfo(); # 更新玩家数据信息
Event::trigger('pay', array('amt' => $order->amount)); # 触发充值事件
CLog::pay("订单发货成功: $cpOrderId");
return Resp::ok(# 返回
array('cash' => ctx()->baseInfo->cash, # # 直接将游戏币的最新值返回给客户端
'charge_amt' => ctx()->baseInfo->charge_amt, # 充值总记录
'store' => ctx()->store, # # 背包
'goods' => $item->goods, # # 发货内容
'count' => $product_count, # # 发货数量
)
);
}
/**
* 检查删档内测订单
*/
static function checkDeltest() {
$uid = req()->uid;
if (ctx()->privateState->deltest == 1) {
$orders = daoInst()->select()->from('tpl_order_tab_deltest')
->where('uid')->eq($uid)
->andwhere('status')->eq(1)
->fetchall();
if (count($orders) > 0) { # 有充值记录
foreach ($orders as $order) {
// 翻倍发放砖石
isEditor() and $order = new pay\dbOrder();
$rmb = intval($order->amount / 100); # 计算充值金额(元)
EmailProc::SendDelTestMail(req()->zoneid, $uid, $rmb);
CLog::pay(req()->uid . '发送删档内侧补偿邮件' . $order->cpOrderId);
}
}
ctx()->privateState->deltest = 0;
}
// CLog::pay('删档内测补偿检查');
}
/**
* 检查异常订单, 补发道具
*/
public static function selfhelpCheckOrders() {
$uid = req()->uid;
$orders = daoInst()->select()
->from('tpl_order_tab')
->where('uid')->eq($uid)
->andWhere('status')->eq(1)
->andWhere('drawed_ts')->le(0)
->fetchAll();
if (count($orders) > 0) {
foreach ($orders as $order) {
// 准备补发
$product_id = $order->product_id;
$product_count = $order->product_count;
$typid = substr("$product_id", 0, 3); # 提取商品编号前缀
$goods = '';
switch ($typid) {
case '802': # 神秘商城物品
$item = GameConfig::secretshop_typeId_getItem($product_id);
break;
case '801': # 商城物品
$item = GameConfig::shop_getItem($product_id);
break;
default :
return Resp::err(ErrCode::pay_systembusy_err);
}
if (!$item) {
return Resp::err(ErrCode::pay_shopItem_cosnt_goods_err);
}
if ($item->pricetype != 0) { # 并非人民币定价
CLog::pay(" 道具付费类型异常:" . $product_id);
return Resp::err(ErrCode::pay_m_type_err);
}
for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况
StoreProc::AddMultiItemInStore($item->goods, 5); # 发货
}
$goods .= $item->goods;
$n = daoInst()->update(self::orderTab) # 更新订单状态
->data(array('drawed_ts' => now()))
->where('cpOrderId')->eq($order->cpOrderId)
->exec();
if (!$n) { # 影响条数应为1
CLog::pay(req()->uid . ' 登录补发订单失败 ' . $order->cpOrderId);
return Resp::err(ErrCode::err_db); # 数据库操作失败
}
ctx()->baseInfo->charge_amt += $order->amount; # 历史充值记录(单位分)
UserProc::updateUserInfo(); # 回写玩家数据
CLog::pay(req()->uid . ' 登录补发订单 ' . $order->cpOrderId);
}
return Resp::ok(# 返回
array('cash' => ctx()->baseInfo->cash, # # 直接将游戏币的最新值返回给客户端
'store' => ctx()->store, # # 背包
'goods' => $goods, # # 发货内容
'count' => count($orders), # # 发货数量
'msg' => "找到并处理" . count($orders) . "条未发货订单."
));
}
return Resp::ok('ok'); # everything is ok!
}
//
//
//
/**
* 8810 免费或利用【游戏内货币】获取神秘商城物品
* 刷新规则: 根据玩家拥有的英雄、装备、道具等数据进行刷新。(因英雄、道具、装备数量不足以支撑该刷新规则,目前先按照随机刷新做,几率平等)
*/
public static function m_pay_getDynamic() {
$user = ctx();
$userSecretshop = new Info_UserSecretshop($user->userSecretshop);
// 参数提取
$refreshType = req()->paras[0]; # 刷新类型(参数)0,不刷,1,免费刷,2,钻石刷
switch ($refreshType) {
case 1: # 免费刷
if (now() < $userSecretshop->lastRefreshTs + glc()->secretshop_refresh_interval) { // 检查是否达到免费刷新时间了, 执行自动更新
return Resp::err(ErrCode::pay_secretshopt_freeRefresh_Time);
}
break;
case 2: # 钻石刷
if (glc()->secretshop_refresh_maxtimes <= $userSecretshop->refreshedTimes) { // 检查刷新次数, 已达上限, 返回错误信息
return Resp::err(ErrCode::pay_refresh_times);
} # 可以继续刷新,
$cishu = $userSecretshop->refreshedTimes + 1; # 下次
$amt = GameConfig::secretshop_refresh_getItem($cishu)->price;
if (!$user->base()->Consume_Cash($amt)) { # 扣除本次所需费用, 余额不足, 返回错误信息
return Resp::err(ErrCode::notenough_cash_msg);
}
$userSecretshop->refreshedTimes++; # 增加当天付费刷新计数
break;
case 0: # 不刷
default : # 默认不刷
// do nothing.
break;
}
if ($refreshType != 0) { # 是否刷新
$err = self::refreshDynamicShopItems($userSecretshop); # 更新物品表
if ($err) {
return Resp::err($err);
}
$user->userSecretshop = $userSecretshop;
ctx($user);
UserProc::updateUserInfo();
}
// 返回最新物品表
return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
'gold' => $user->baseInfo->gold,
'tili' => $user->baseInfo->tili,
'cash' => $user->baseInfo->cash,
'uss' => $userSecretshop, # # 当前神秘商城数据
));
}
/**
* 更新神秘商城物品
* @param Info_UserSecretshop $userSecretshop Description
*/
private static function refreshDynamicShopItems(&$userSecretshop) {
$userSecretshop->lastRefreshTs = now();
// todo: 这里补完更新物品的函数, // 第一版: 随机
$userSecretshop->currentItems = ObjectInit();
for ($i = 1; $i <= 3; $i++) { # 3种类型的商品
$arr = GameConfig::secretshop_goodsType_getItem($i);
if (count($arr) > 0) {
$err = self::Dice(GameConfig::secretshop_goodsType_getItem($i), 1, $userSecretshop); # 一个种类一次1个物品
if ($err) {
return $err;
}
}
}
return ErrCode::ok;
}
/**
* 投骰子
* @param assoc_array $arr 奖池物品
* @param int $number 提取数量
* @return string itemid,num;itemid,num;...
*/
private static function Dice($arr, $number, &$userSecretshop) {
$max = 0; # 计算物品权重总和
array_walk($arr, function ($value) use (&$max) {
$max += $value->probability;
});
if (!$max) { # 配置数据有问题
return ErrCode::err_const_no;
}
for ($i = 0; $i < $number; $i++) {
$rnd = CommUtil::random(1, $max); # 投骰子
$start = 0;
$rew = null;
foreach ($arr as $item) { # 循环判断落入那个物品上
if (CommUtil::isPropertyExists($item, 'probability') // #
&& $start < $rnd && $rnd <= $start + $item->probability) { # 落入区间
$rew = $item; # 记录物品
break;
}
$start += $item->probability; # 继续判断是否落入下一物品的区间
} # foreach end
if (!$rew) {
return ErrCode::lottery_noselecteditem;
}
$id = $rew->typeId;
$userSecretshop->currentItems->$id = 0;
} # for end
return ErrCode::ok;
}
/**
* 清理每日各种上限
*/
private static function clearDailyLimits() {
$userSecretshop = new Info_UserSecretshop(ctx()->userSecretshop);
$userSecretshop->refreshedTimes = 0;
ctx()->userSecretshop = $userSecretshop;
}
/**
* [8809]【游戏内货币】购买神秘商城物品
* 规则: 商城物品会刷新
*/
public static function m_pay_buyDynamic() {
$user = new Data_UserGame(ctx());
$userSecretshop = new Info_UserSecretshop($user->userSecretshop);
$itemId = req()->paras[0]; # 商品id (点一次购买一个)
$num = 1; # 暂时固定为一次购买一个
#
my_Assert(CommUtil::isPropertyExists($userSecretshop->currentItems, $itemId), ErrCode::pay_secretshop_noitem_err);
$cishu = $userSecretshop->currentItems->$itemId; # 购买次数
my_Assert($cishu < glc()->secretshop_itembuy_maxtimes, ErrCode::pay_secretshop_buytimes); # 判断购买次数
$shopItem = GameConfig::secretshop_typeId_getItem($itemId); # 常量数据
$amt = $shopItem->price * pow(2, $cishu); # 计算价格
switch ($shopItem->pricetype) {
case 1:
my_Assert($user->base()->Consume_Cash($amt), ErrCode::notenough_cash_msg); # 扣除钻石
break;
case 2:
my_Assert($user->base()->Consume_Gold($amt), ErrCode::notenough_gold_msg); # 扣除金币
break;
default :
return Resp::err(ErrCode::pay_m_type_err);
}
// 道具解包/发货
$err = self::expendSecretShopItem($shopItem, $num); # 发放商品
if ($err != ErrCode::ok) { # 发货失败
return Resp::err($err);
}
$userSecretshop->currentItems->$itemId += 1; # 购买次数+1
$user->userSecretshop = $userSecretshop;
ctx($user);
UserProc::updateUserInfo(); # 回写数据
// StatProc::secretShopbuy($req->zoneid, $req->uid, $itemId, $num); # 统计/监控数据
return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
'gold' => $user->baseInfo->gold,
'tili' => $user->baseInfo->tili,
'cash' => $user->baseInfo->cash,
'store' => $user->baseInfo->store, # # 背包,(装备、碎片、。。)
'heros' => $user->baseInfo->heros # # 角色
));
//
}
/**
* [8807]【游戏内货币】购买普通商城物品
*/
public static function m_pay() {
$user = ctx(); # user引用
my_Assert(count(req()->paras) >= 3, ErrCode::parasnotenough_msg); # 参数不足
list($paytype, $itemId, $num) = req()->paras; # 付费类型, 1.钻石, 2.金币 ,道具ID ,数量, 默认为1
my_Assert($num >= 1, ErrCode::paras_err); # 参数非法,
$shopItem = GameConfig::shop_getItem($itemId); # 取商品的常量数据
my_Assert(isset($shopItem), ErrCode::err_const_no); # 检测是否存在道具的常量数据
my_Assert($shopItem->pricetype == $paytype, ErrCode::pay_price_err); # 商品定价类型检查
$amt = $shopItem->price; # 道具价格(钻石)
my_Assert($amt > 0, ErrCode::pay_price_err); # 商品定价数值检查
$bDeal = false; # 成交标志位
switch ($paytype) { # 1. 钻石, 2. 金币, other:非法
case 1: # 钻石
$bDeal = ctx()->base()->Consume_Cash($amt); # 更新(扣除)玩家游戏币(钻石)余额
my_Assert($bDeal, ErrCode::notenough_cash_msg); # 防范扣除失败
break;
case 2: # 金币
$bDeal = $user->base()->Consume_Gold($amt * $num); # 更新玩家金币余额
my_Assert($bDeal, ErrCode::notenough_gold_msg); # 防范扣除失败
break;
default : # 未知的支付类型
return Resp::err(ErrCode::pay_m_type_err);
}
my_Assert($bDeal, ErrCode::err_innerfault); # 交易失败
$err = self::expendShopItem($shopItem, $num); # 发放商品(普通商城只有金币和体力)
my_Assert(ErrCode::ok == $err, $err); # 防范发货失败
UserProc::updateUserInfo(); # 回写数据
// StatProc::shopbuy($zoneid, $uid, $itemId, $num); # 统计/监控数据
return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
'gold' => $user->baseInfo->gold,
'tili' => $user->baseInfo->tili,
'cash' => $user->baseInfo->cash,
'store' => $user->store
));
}
/**
* 解包商城物品并发货
* @param sm_Shop $shopItem
* @param int $num 数量
*/
private static function expendShopItem($shopItem, $num) {
for ($i = 0; $i < $num; $i++) {
$err = StoreProc::AddMultiItemInStore($shopItem->goods, '商城');
my_Assert(ErrCode::ok == $err, $err);
}
return ErrCode::ok;
}
/**
* 道具解包并发货(神秘商城)
* @param sm_secretshop $shopItem
* @param type $num
*/
private static function expendSecretShopItem($shopItem, $num) {
for ($i = 0; $i < $num; $i++) {
$err = StoreProc::AddMultiItemInStore($shopItem->goods, '神秘商城');
if ($err) {
return $err;
}
}
return ErrCode::ok;
}
//
//
//
//
/**
* [8802] 领取首付礼包
*/
public static function m_GetFirstPayGift() {
$itemId = glc()->FirstPay_ItemId;
$privateState = ctx()->privateState;
if (CommUtil::isPropertyExists($privateState, "firstPayGift") #
&& $privateState->firstPayGift) { # 如果已经领取首付礼包
return Resp::err(ErrCode::pay_firstpaygetted);
}
my_Assert(ctx()->baseInfo->charge_amt > 0, ErrCode::pay_firstpayno_err); # 如果尚未完成首付
$itemModel = GameConfig::shop_getItem($itemId); # 取商品常量
if ($itemModel == null) { # 检测首付礼包是否存在
return Resp::err(ErrCode::err_const_no);
}
ctx()->privateState->firstPayGift = true; # 设置首付标志
StoreProc::AddMultiItemInStore($itemModel->goods); # 发放首付礼包到玩家仓库
UserProc::updateUserInfo(); # 更新玩家数据
return Resp::ok(array('itemid' => $itemId,
'rewardstr' => $itemModel->goods,
'store' => ctx()->store)); # 回送成功信息
}
//
//
//
//
}