PayProc.php 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. <?php
  2. namespace loyalsoft;
  3. require_once __DIR__ . '/../service_call/pay/official/pay_op.php'; // 日志类型定义
  4. require_once __DIR__ . '/PayProc/MLogType.php'; // 日志类型定义
  5. if (PLAT == 'web') {
  6. include_once __DIR__ . '/PayProc/WebPayProc.php';
  7. }
  8. /**
  9. * 付费、游戏内消费相关处理
  10. * 全部动态交易数据需要保存到db作为[存根]
  11. * @version <br/>
  12. * 4.0.0 第四版: 言灵世界 商城模块
  13. * 2.2.0 第三版: 独立的游戏币<元宝>, 面向多渠道的充值模式, 拉起充值成功后, 给玩家发放元宝. 游戏内部消费元宝,钻石和金币.可以用元宝购买金币和钻石.这一版在上面的PayProc中 * 2015年9月23日 <br/>
  14. * 2.1.0 mn_pay mn_AddUserCash ... 以 mn_ 打头的函数是第二版, 修改为伪托管模式,除了充值的时候跟腾讯通讯,其余时间自己管理游戏币:钻石. * 2015年7月23日 <br/>
  15. * 2.0.1 m_pay m_AddUserCash ... 以 m_ 打头的函数是第一版, 完全按照应用宝官方要求托管游戏币的模式开发的. * 2015年4月23日 <br/>
  16. * 1.0.0 Created at 2016-4-20. by --gwang <br/>
  17. * @author gwang (mail@wanggangzero.cn)
  18. * @copyright © 2016-4-20, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  19. */
  20. class PayProc {
  21. const orderTab = 'tpl_order_tab';
  22. /**
  23. * 逻辑分发
  24. * 所有的Proc中必须有这样一个方法
  25. */
  26. public static function procMain() {
  27. switch (req()->cmd) {
  28. // 支付相关的活动
  29. case CmdCode::cmd_pay_getfirstpaygift: # 8802 领取首充礼包
  30. return PayProc::m_GetFirstPayGift();
  31. // <editor-fold defaultstate="collapsed" desc=" 手机多渠道版 mpay ">
  32. case CmdCode::cmd_mpay_pay: # 8807 消费..
  33. return self::m_pay(); # ::==> 购买普通商城物品
  34. case CmdCode::cmd_mpay_get_balance: # 8808 刷新账号余额
  35. return self::m_refreshChargeOrders(); # ::==> 刷新订单-领取充值金额
  36. case CmdCode::cmd_mpay_buyDynamic: # 8809 购买动态商城物品
  37. return self::m_pay_buyDynamic();
  38. case CmdCode::cmd_mpay_getDynamic: # 8810 刷新神秘商城物品
  39. return self::m_pay_getDynamic();
  40. case CmdCode::cmd_mpay_selfCheckOrders: # 8811 自助检查异常订单
  41. return self::selfhelpCheckOrders();
  42. case CmdCode::cmd_mpay_getPayRecords: # 8812 查询订单记录
  43. return self::GetPayRecoreds();
  44. // </editor-fold>
  45. // <editor-fold defaultstate="collapsed" desc=" 支付新版 2021.11.16 ">
  46. case CmdCode::cmd_mpay_PayDeliverGoods: # 8813
  47. return self::PayDeliverGoods();
  48. case CmdCode::cmd_mpay_UserRechargeDrawPrize:
  49. return self::UserRechargeDrawPrize();
  50. case CmdCode::cmd_mpay_text:
  51. return self::text();
  52. // </editor-fold>
  53. default:
  54. return Resp::err(ErrCode::cmd_err);
  55. }
  56. }
  57. static $retArr;
  58. static function text() {
  59. //$result = pay_op::CheckAndDrawOrder(req()->uid,1912111624,array(new PayProc,'distributePayGoods_NEW'));
  60. //my_Assert($result->err != 0, ErrCode::shop_firstRechargeNotRepeat);
  61. //var_dump($result);
  62. return Resp::ok(array(
  63. "ret"=>self::$retArr,
  64. ));
  65. }
  66. static function distributePayGoods_NEW($order) {
  67. $cash = 10;
  68. self::$retArr = array();
  69. self::$retArr[] = "2,".$cash;
  70. }
  71. /**
  72. * 领取奖励
  73. * @return type
  74. */
  75. static function UserRechargeDrawPrize() {
  76. list($type,$typeId) = req()->paras;
  77. $user = req()->userInfo->game;
  78. self::$retArr = array();
  79. switch ($type) {
  80. case Enum_Recharge::FirstRecharge://首冲
  81. my_Assert($user->pay->firstRechage == 0, ErrCode::shop_firstRechargeNotRepeat);
  82. StoreProc::AddMultiItemInStore(GameConfig::globalsettings()->firstRechargePrizes);
  83. $user->pay->firstRechage = 1;
  84. self::$retArr[] = GameConfig::globalsettings()->firstRechargePrizes;
  85. break;
  86. case Enum_Recharge::DaliySpecialPackages://每日特惠
  87. my_Assert(!in_array($typeId, $user->shopdata->daliySpecialPackages), ErrCode::shop_daliySpecialRewardNotRepeat);
  88. $mo = GameConfig::shop_limit_getItem($typeId);
  89. my_Assert($mo != null, ErrCode::err_const_no);
  90. if($mo->price != 0){//购买60元7天特惠,则不是免费的礼包现在也可以领取。这里校验一下
  91. //my_Assert($user->shopdata->daliySpecial_ts!= 0, ErrCode::shop_daliySpecialRewardNotRepeat);
  92. $ts = $user->shopdata->daliySpecial_ts + 7*24*60*60;
  93. my_Assert(now() < $ts, ErrCode::shop_daliySpecialRewardNotRepeat);
  94. }
  95. $itemid = explode(',', $mo->reward)[0];
  96. $itemMO = GameConfig::item_package_getItem($itemid);
  97. my_Assert(null != $itemMO, ErrCode::err_const_no);
  98. StoreProc::AddMultiItemInStore($itemMO->contents);
  99. self::$retArr[] =$itemMO->contents;
  100. $shopdata = new Info_UserShop(req()->userInfo->game->shopdata);
  101. $shopdata->daliySpecialPackages[] = $typeId;
  102. req()->userInfo->game->shopdata = $shopdata;
  103. break;
  104. case Enum_Recharge::RechargeRebate://充值返利
  105. $mo = GameConfig::rechargeRebate_getItem($typeId);
  106. my_Assert($mo != null, ErrCode::err_const_no);
  107. my_Assert($user->baseInfo->charge_amt >= $mo->rmb, ErrCode::shop_RechargeRebateRmbNotEnough);
  108. my_Assert(!in_array($typeId, $user->shopdata->rechargeRebateRewardsList) , ErrCode::shop_RechargeRebateRewardNotRepeat);
  109. StoreProc::AddMultiItemInStore($mo->rewards);
  110. self::$retArr[] =$mo->rewards;
  111. break;
  112. case Enum_Recharge::LimitBuy://限购中免费礼包领取
  113. $packageCfg = GameConfig::shop_limit_getItem($typeId);
  114. my_Assert(null != $packageCfg, ErrCode::err_const_no);
  115. my_Assert($packageCfg->price == 0, ErrCode::shop_limit_NotFree);
  116. self::checklimitBuyRecharge($typeId);
  117. break;
  118. default:
  119. break;
  120. }
  121. req()->userInfo->game = $user;
  122. UserProc::updateUserInfo();
  123. return Resp::ok(array(
  124. "ret"=>self::$retArr,
  125. "pay"=>$user->pay,
  126. "shopdata"=>req()->userInfo->game->shopdata,
  127. "base" => $user->baseInfo,
  128. "store" => $user->store,
  129. ));
  130. }
  131. static function checklimitBuyRecharge($packageId) {
  132. //$packageId = req()->paras[0]; # 参数; 礼包id
  133. $shopdata = new Info_UserShop(req()->userInfo->game->shopdata);
  134. $packageCfg = GameConfig::shop_limit_getItem($packageId);
  135. my_Assert(null != $packageCfg, ErrCode::err_const_no);
  136. $arr = array();
  137. switch ((int) $packageCfg->subType) {
  138. case 1:
  139. $shopdata->purchasedDailyLimitPackages[] = $packageId;
  140. $arr = $shopdata->purchasedDailyLimitPackages;
  141. break;
  142. case 2:
  143. $shopdata->purchasedWeeklyLimitPackages[] = $packageId;
  144. $arr = $shopdata->purchasedWeeklyLimitPackages;
  145. break;
  146. case 3:
  147. $shopdata->purchasedMonthlyLimitPackages[] = $packageId;
  148. $arr = $shopdata->purchasedMonthlyLimitPackages;
  149. break;
  150. default:
  151. Err(ErrCode::err_innerfault);
  152. }
  153. $hasN = count(array_filter($arr, function ($val)use ($packageId) {
  154. return $val == $packageId;
  155. }));
  156. my_Assert($hasN <= $packageCfg->limit_num, ErrCode::shop_limit_max);
  157. $itemid = explode(',', $packageCfg->reward)[0]; # 奖励礼包Id
  158. $itemMO = GameConfig::item_package_getItem($itemid);
  159. my_Assert(null != $itemMO, ErrCode::err_const_no);
  160. $err = StoreProc::AddMultiItemInStore($itemMO->contents); # 发放奖励
  161. self::$retArr[] = $itemMO->contents;
  162. my_Assert(ErrCode::ok == $err, $err);
  163. req()->userInfo->game->shopdata = $shopdata; # 回写数据
  164. }
  165. /**
  166. * 充值发货
  167. */
  168. static function PayDeliverGoods() {
  169. list($cpOrderId) = req()->paras;
  170. $user = req()->userInfo->game;
  171. $result = pay_op::CheckAndDrawOrder(req()->uid,$cpOrderId,array(new PayProc,'distributePayGoods'));
  172. my_Assert($result->err == 0, ErrCode::pay_fail);
  173. req()->userInfo->game = $user;
  174. NormalEventProc::OnPaySuccess();
  175. UserProc::updateUserInfo(); # 回写玩家数据
  176. return Resp::ok(array(
  177. "ret"=>self::$retArr,
  178. "pay"=>$user->pay,
  179. "base" => $user->baseInfo,
  180. "shopdata"=>$user->shopdata,
  181. "store" => $user->store,
  182. ));
  183. }
  184. //发货
  185. static function distributePayGoods($order = null) {
  186. my_Assert($order->product_id != null, ErrCode::pay_order_product_id);
  187. $user = req()->userInfo->game;
  188. self::$retArr = array();
  189. if ($order->product_id >= 6 && $order->product_id <= 1000) {//充值表
  190. $mo = GameConfig::recharge_getItem($order->product_id);
  191. my_Assert($mo != null, ErrCode::err_const_no);
  192. $cash = $mo->rmd *10;
  193. if($user->baseInfo->charge_amt <= 0){
  194. $cash = $mo->rmd *10* $mo->firstDouble;
  195. }
  196. $user->base()->Add_Cash($cash);
  197. self::$retArr[] = "2,".$cash;
  198. }
  199. elseif ($order->product_id >= 801001 && $order->product_id <= 801999) {//限购
  200. self::checklimitBuyRecharge($order->product_id);
  201. }
  202. elseif ($order->product_id >= 804001 && $order->product_id <= 804999) {//每日特惠
  203. $mo = GameConfig::shop_limit_getItem($order->product_id);
  204. if($mo == null){//校验看看是不是60元特惠礼包
  205. $list = GameConfig::shop_limit_type_getItemArray(Enum_Recharge::DaliySpecialPackages);
  206. $cur = 0;
  207. foreach ($list as $item) {
  208. $cur += $item->price;
  209. }
  210. //这临时先注释为了测试正式的应该解开注释
  211. //my_Assert($cur == $order->amount, ErrCode::err_const_no);
  212. $user->shopdata->daliySpecial_ts = now();
  213. } else {
  214. $itemid = explode(',', $mo->reward)[0];
  215. $itemMO = GameConfig::item_package_getItem($itemid);
  216. my_Assert(null != $itemMO, ErrCode::err_const_no);
  217. StoreProc::AddMultiItemInStore($itemMO->contents);
  218. $user->shopdata->daliySpecialPackages[] = $mo->typeId;
  219. self::$retArr[] = $itemMO->contents;
  220. }
  221. }
  222. elseif ($order->product_id >= 805001 && $order->product_id <= 805999) {//限时
  223. $mo = GameConfig::shop_limit_getItem($order->product_id);
  224. my_Assert($mo, ErrCode::err_const_no);
  225. my_Assert(!in_array($order->product_id, $user->shopdata->limitTsActiveRewardsList), ErrCode::err_const_no);
  226. $user->shopdata->limitTsActiveRewardsList[] = $mo->typeId;
  227. $itemid = explode(',', $mo->reward)[0];
  228. $itemMO = GameConfig::item_package_getItem($itemid);
  229. my_Assert(null != $itemMO, ErrCode::err_const_no);
  230. StoreProc::AddMultiItemInStore($itemMO->contents); //领取奖励
  231. //StoreProc::AddMultiItemInStore($mo->reward);
  232. self::$retArr[] = $itemMO->contents;
  233. }
  234. elseif ($order->product_id >= 901001 && $order->product_id <= 999999) {//月卡
  235. $shopdata = new Info_UserShop(req()->userInfo->game->shopdata);
  236. $packageCfg = GameConfig::shop_monthVIP_getItem($order->product_id);
  237. my_Assert(null != $packageCfg, ErrCode::err_const_no);
  238. if ($packageCfg->subType == 4) {
  239. my_Assert($shopdata->monthlyVIP1_ts + $packageCfg->ExpireTs * 3600 * 24 < now(), ErrCode::shop_monthlyvip_buyed);
  240. } elseif ($packageCfg->subType == 5) {
  241. my_Assert($shopdata->monthlyVIP2_ts + $packageCfg->ExpireTs * 3600 * 24 < now(), ErrCode::shop_monthlyvip_buyed);
  242. }
  243. $err = StoreProc::AddMultiItemInStore($packageCfg->pri_reward); # 发放一次性奖励
  244. self::$retArr[] = $packageCfg->pri_reward;
  245. my_Assert(ErrCode::ok == $err, $err);
  246. if ($packageCfg->subType == 4) {
  247. $shopdata->monthlyVIP1_ts = 3600 * 24 * (totalDays() + 1) - 1;
  248. } elseif ($packageCfg->subType == 5) {
  249. $shopdata->monthlyVIP2_ts = 3600 * 24 * (totalDays() + 1) - 1;
  250. }
  251. EmailProc::SendMonthlyVIPDailyReward(req()->zoneid, req()->uid, $packageCfg->name, $packageCfg->daily_reward);
  252. req()->userInfo->game->shopdata = $shopdata;
  253. }
  254. $user->baseInfo->charge_amt += $order->amount;
  255. req()->userInfo->game = $user;
  256. return true;
  257. //CLog::pay("支付奖励回存状态".$ret);
  258. //return $ret == ErrCode::ok? true:false;
  259. }
  260. static function checkAmount($order) {
  261. my_Assert($order->product_id != null, ErrCode::pay_order_product_id);
  262. if ($order->product_id >= 6 && $order->product_id <= 1000) {//充值表
  263. $mo = GameConfig::recharge_getItem($order->product_id);
  264. my_Assert($mo != null, ErrCode::err_const_no);
  265. my_Assert($order->amount == $mo->rmd, ErrCode::pay_price_err);
  266. }
  267. elseif ($order->product_id >= 801001 && $order->product_id <= 801999) {//限购
  268. //该功能暂时没有开发
  269. }
  270. elseif ($order->product_id >= 804001 && $order->product_id <= 804999) {//每日特惠
  271. $mo = GameConfig::shop_limit_getItem($order->product_id);
  272. $num = 0;
  273. if($mo == null){//校验看看是不是60元特惠礼包
  274. $list = GameConfig::shop_limit_type_getItemArray(Enum_Recharge::DaliySpecialPackages);
  275. $cur = 0;
  276. foreach ($list as $item) {
  277. $cur += $item->price;
  278. }
  279. $num = $cur;
  280. } else {
  281. $num = $mo->price;
  282. }
  283. my_Assert($num == $order->amount, ErrCode::pay_price_err);
  284. }
  285. elseif ($order->product_id >= 805001 && $order->product_id <= 805999) {//限时
  286. //该功能暂时没有开发
  287. }
  288. elseif ($order->product_id >= 901001 && $order->product_id <= 999999) {//月卡
  289. $packageCfg = GameConfig::shop_monthVIP_getItem($order->product_id);
  290. my_Assert(null != $packageCfg, ErrCode::err_const_no);
  291. my_Assert($packageCfg->price == $order->amount, ErrCode::pay_price_err);
  292. }
  293. return true;
  294. }
  295. /**
  296. * 8812 查询充值记录
  297. */
  298. static function GetPayRecoreds() {
  299. $uid = req()->uid;
  300. $table = "tpl_order_tab";
  301. $arr = daoInst()->select(" cpOrderId as '订单' ,product_name as '道具',amount as '金额' ,from_unixtime(order_ts) as '时间' ")->from($table)
  302. ->where("uid")->eq($uid)
  303. ->andWhere("status")->eq(1)
  304. ->fetchall();
  305. return Resp::ok($arr);
  306. }
  307. //
  308. // <editor-fold defaultstate="collapsed" desc=" 移动支付 - 刷新订单 ">
  309. /**
  310. * 刷新充值订单(领取充值结果)
  311. */
  312. public static function m_refreshChargeOrders() {
  313. # 客户端参数解析
  314. $uid = req()->uid; # userID
  315. $zoneid = req()->zoneid; # 分区Id
  316. if (count(req()->paras) <= 0) { # 参数为空, 执行自检逻辑
  317. return self::selfhelpCheckOrders();
  318. }
  319. $cpOrderId = req()->paras[0]; # 后台订单编号
  320. if (!$uid || ($zoneid < 1) || strlen($cpOrderId) != 16) { # 订单编号长16位
  321. return Resp::err(ErrCode::paras_err);
  322. }
  323. $order = daoInst()->select()->from(self::orderTab) # 取订单数据
  324. ->where('cpOrderId')->eq($cpOrderId)
  325. ->limit(1)->fetch();
  326. if (!$order) {
  327. // var_dump($order);
  328. CLog::pay(' 订单不存在! ' . $cpOrderId);
  329. return Resp::err(ErrCode::pay_order_no);
  330. }
  331. if (false === strpos($uid, $order->uid)) { # UID不符
  332. return Resp::err(ErrCode::pay_order_uid);
  333. }
  334. if ($order->status != 1) {
  335. CLog::pay(' 订单尚未完成支付!');
  336. return Resp::err(ErrCode::pay_order_paystatus);
  337. }
  338. if ($order->drawed_ts > 0) { # 定单已经发过货了
  339. CLog::pay(' 订单重复请求发货!' . $cpOrderId);
  340. return Resp::err(ErrCode::pay_order_drawed);
  341. }
  342. // 准备发货
  343. $product_id = $order->product_id;
  344. $product_count = $order->product_count;
  345. $typid = substr("$product_id", 0, 3); # 提取商品编号前缀
  346. switch ($typid) {
  347. case '802': # 神秘商城物品
  348. $item = GameConfig::secretshop_typeId_getItem($product_id);
  349. break;
  350. case '801': # 商城物品
  351. $item = GameConfig::shop_getItem($product_id);
  352. break;
  353. default :
  354. return Resp::err(ErrCode::pay_systembusy_err);
  355. }
  356. my_Assert(isset($item), ErrCode::pay_shopItem_cosnt_goods_err);
  357. if ($item->pricetype != 0) {
  358. CLog::pay(" 道具付费类型异常:" . $product_id);
  359. return Resp::err(ErrCode::pay_m_type_err);
  360. }
  361. for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况
  362. StoreProc::AddMultiItemInStore($item->goods, 5); # 发货
  363. }
  364. $n = daoInst()->update(self::orderTab)
  365. ->data(array('drawed_ts' => now()))
  366. ->where('cpOrderId')->eq($cpOrderId)
  367. ->exec();
  368. my_Assert($n > 0, ErrCode::err_db); # 数据库操作失败
  369. req()->userInfo->game->baseInfo->charge_amt += $order->amount; # 历史充值记录(单位分)
  370. UserProc::updateUserInfo(); # 更新玩家数据信息
  371. Event::trigger('pay', array('amt' => $order->amount)); # 触发充值事件
  372. CLog::pay("订单发货成功: $cpOrderId");
  373. return Resp::ok(# 返回
  374. array('cash' => req()->userInfo->game->baseInfo->cash, # # 直接将游戏币的最新值返回给客户端
  375. 'charge_amt' => req()->userInfo->game->baseInfo->charge_amt, # 充值总记录
  376. 'store' => req()->userInfo->game->store, # # 背包
  377. 'goods' => $item->goods, # # 发货内容
  378. 'count' => $product_count, # # 发货数量
  379. )
  380. );
  381. }
  382. /**
  383. * 检查内侧订单
  384. */
  385. static function checkDeltest() {
  386. $uid = req()->uid;
  387. if (!isset(req()->userInfo->game->privateState->deltest)) {
  388. $orders = daoInst()->select()->from('tpl_order_tab_deltest')
  389. ->where('uid')->eq(substr($uid, strpos($uid, "-") + 1))
  390. ->andwhere('status')->eq(1)
  391. ->fetchall();
  392. if (count($orders) > 0) { # 有充值记录
  393. foreach ($orders as $order) {
  394. // 准备补发
  395. $product_id = $order->product_id;
  396. $product_count = $order->product_count;
  397. $typid = substr("$product_id", 0, 3); # 提取商品编号前缀
  398. switch ($typid) {
  399. case '802': # 神秘商城物品
  400. $item = GameConfig::secretshop_typeId_getItem($product_id);
  401. break;
  402. case '801': # 商城物品
  403. $item = GameConfig::shop_getItem($product_id);
  404. break;
  405. default :
  406. return Resp::err(ErrCode::pay_systembusy_err);
  407. }
  408. if (!$item) {
  409. return Resp::err(ErrCode::pay_shopItem_cosnt_goods_err);
  410. }
  411. if ($item->pricetype != 0) { # 并非人民币定价
  412. CLog::pay(" 道具付费类型异常:" . $product_id);
  413. return Resp::err(ErrCode::pay_m_type_err);
  414. }
  415. for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况
  416. EmailProc::SendDelTestMail(req()->zoneid, $uid, $item->name, $item->goods);
  417. }
  418. CLog::pay(req()->uid . '发送删档内侧补偿邮件' . $order->cpOrderId);
  419. }
  420. }
  421. req()->userInfo->game->privateState->deltest = 0;
  422. }
  423. }
  424. /**
  425. * 检查异常订单
  426. */
  427. public static function selfhelpCheckOrders() {
  428. if ('ios' == PLAT) { # ios版的创建订单时带着前缀了。。。
  429. $uid = req()->uid;
  430. } else {
  431. $uid = substr(req()->uid, strpos(req()->uid, '-') + 1);
  432. }
  433. $orders = daoInst()->select()
  434. ->from('tpl_order_tab')
  435. ->where('uid')->eq($uid)
  436. ->andWhere('status')->eq(1)
  437. ->andWhere('drawed_ts')->le(0)
  438. ->fetchAll();
  439. if (count($orders) > 0) {
  440. foreach ($orders as $order) {
  441. // 准备补发
  442. $product_id = $order->product_id;
  443. $product_count = $order->product_count;
  444. $typid = substr("$product_id", 0, 3); # 提取商品编号前缀
  445. $goods = '';
  446. switch ($typid) {
  447. case '802': # 神秘商城物品
  448. $item = GameConfig::secretshop_typeId_getItem($product_id);
  449. break;
  450. case '801': # 商城物品
  451. $item = GameConfig::shop_getItem($product_id);
  452. break;
  453. default :
  454. return Resp::err(ErrCode::pay_systembusy_err);
  455. }
  456. if (!$item) {
  457. return Resp::err(ErrCode::pay_shopItem_cosnt_goods_err);
  458. }
  459. if ($item->pricetype != 0) { # 并非人民币定价
  460. CLog::pay(" 道具付费类型异常:" . $product_id);
  461. return Resp::err(ErrCode::pay_m_type_err);
  462. }
  463. for ($i = 0; $i < $product_count; $i++) { # 默认为1,还没有设计为n的情况
  464. StoreProc::AddMultiItemInStore($item->goods, 5); # 发货
  465. }
  466. $goods .= $item->goods;
  467. $n = daoInst()->update(self::orderTab) # 更新订单状态
  468. ->data(array('drawed_ts' => now()))
  469. ->where('cpOrderId')->eq($order->cpOrderId)
  470. ->exec();
  471. if (!$n) { # 影响条数应为1
  472. CLog::pay(req()->uid . ' 登录补发订单失败 ' . $order->cpOrderId);
  473. return Resp::err(ErrCode::err_db); # 数据库操作失败
  474. }
  475. req()->userInfo->game->baseInfo->charge_amt += $order->amount; # 历史充值记录(单位分)
  476. UserProc::updateUserInfo(); # 回写玩家数据
  477. CLog::pay(req()->uid . ' 登录补发订单 ' . $order->cpOrderId);
  478. }
  479. return Resp::ok(# 返回
  480. array('cash' => req()->userInfo->game->baseInfo->cash, # # 直接将游戏币的最新值返回给客户端
  481. 'store' => req()->userInfo->game->store, # # 背包
  482. 'goods' => $goods, # # 发货内容
  483. 'count' => count($orders), # # 发货数量
  484. 'msg' => "找到并处理" . count($orders) . "条未发货订单."
  485. ));
  486. }
  487. return Resp::ok('ok'); # everything is ok!
  488. }
  489. // </editor-fold>
  490. //
  491. // <editor-fold defaultstate="collapsed" desc=" 移动支付 - 商城购买 ">
  492. /**
  493. * 【移动支付】获取神秘商城物品
  494. * 刷新规则: 根据玩家拥有的英雄、装备、道具等数据进行刷新。(因英雄、道具、装备数量不足以支撑该刷新规则,目前先按照随机刷新做,几率平等)
  495. */
  496. public static function m_pay_getDynamic() {
  497. $user = req()->userInfo->game;
  498. $userSecretshop = new Info_UserSecretshop($user->userSecretshop);
  499. // 参数提取
  500. $refreshType = req()->paras[0]; # 刷新类型(参数)0,不刷,1,免费刷,2,钻石刷
  501. switch ($refreshType) {
  502. case 1: # 免费刷
  503. if (now() < $userSecretshop->lastRefreshTs + glc()->secretshop_refresh_interval) { // 检查是否达到免费刷新时间了, 执行自动更新
  504. return Resp::err(ErrCode::pay_secretshopt_freeRefresh_Time);
  505. }
  506. break;
  507. case 2: # 钻石刷
  508. if (glc()->secretshop_refresh_maxtimes <= $userSecretshop->refreshedTimes) { // 检查刷新次数, 已达上限, 返回错误信息
  509. return Resp::err(ErrCode::pay_refresh_times);
  510. } # 可以继续刷新,
  511. $cishu = $userSecretshop->refreshedTimes + 1; # 下次
  512. $amt = GameConfig::secretshop_refresh_getItem($cishu)->price;
  513. if (!$user->base()->Consume_Cash($amt)) { # 扣除本次所需费用, 余额不足, 返回错误信息
  514. return Resp::err(ErrCode::notenough_cash_msg);
  515. }
  516. $userSecretshop->refreshedTimes++; # 增加当天付费刷新计数
  517. break;
  518. case 0: # 不刷
  519. default : # 默认不刷
  520. // do nothing.
  521. break;
  522. }
  523. if ($refreshType != 0) { # 是否刷新
  524. $err = self::refreshDynamicShopItems($userSecretshop); # 更新物品表
  525. if ($err) {
  526. return Resp::err($err);
  527. }
  528. $user->userSecretshop = $userSecretshop;
  529. req()->userInfo->game = $user;
  530. UserProc::updateUserInfo();
  531. }
  532. // 返回最新物品表
  533. return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
  534. 'gold' => $user->baseInfo->gold,
  535. 'tili' => $user->baseInfo->tili,
  536. 'cash' => $user->baseInfo->cash,
  537. 'uss' => $userSecretshop, # # 当前神秘商城数据
  538. ));
  539. }
  540. /**
  541. * 更新神秘商城物品
  542. * @param Info_UserSecretshop $userSecretshop Description
  543. */
  544. private static function refreshDynamicShopItems(&$userSecretshop) {
  545. $userSecretshop->lastRefreshTs = now();
  546. // todo: 这里补完更新物品的函数, // 第一版: 随机
  547. $userSecretshop->currentItems = ObjectInit();
  548. for ($i = 1; $i <= 3; $i++) { # 3种类型的商品
  549. $arr = GameConfig::secretshop_goodsType_getItem($i);
  550. if (count($arr) > 0) {
  551. $err = self::Dice(GameConfig::secretshop_goodsType_getItem($i), 1, $userSecretshop); # 一个种类一次1个物品
  552. if ($err) {
  553. return $err;
  554. }
  555. }
  556. }
  557. return ErrCode::ok;
  558. }
  559. /**
  560. * 投骰子
  561. * @param assoc_array $arr 奖池物品
  562. * @param int $number 提取数量
  563. * @return string itemid,num;itemid,num;...
  564. */
  565. static function Dice($arr, $number, &$userSecretshop) {
  566. $max = 0; # 计算物品权重总和
  567. array_walk($arr, function ($value) use (&$max) {
  568. $max += $value->probability;
  569. });
  570. if (!$max) { # 配置数据有问题
  571. return ErrCode::err_const_no;
  572. }
  573. for ($i = 0; $i < $number; $i++) {
  574. $rnd = CommUtil::random(1, $max); # 投骰子
  575. $start = 0;
  576. $rew = null;
  577. foreach ($arr as $item) { # 循环判断落入那个物品上
  578. if (CommUtil::isPropertyExists($item, 'probability') // #
  579. && $start < $rnd && $rnd <= $start + $item->probability) { # 落入区间
  580. $rew = $item; # 记录物品
  581. break;
  582. }
  583. $start += $item->probability; # 继续判断是否落入下一物品的区间
  584. } # foreach end
  585. if (!$rew) {
  586. return ErrCode::lottery_noselecteditem;
  587. }
  588. $id = $rew->typeId;
  589. $userSecretshop->currentItems->$id = 0;
  590. } # for end
  591. return ErrCode::ok;
  592. }
  593. /**
  594. * 清理每日各种上限
  595. */
  596. private static function clearDailyLimits() {
  597. $userSecretshop = new Info_UserSecretshop(req()->userInfo->game->userSecretshop);
  598. $userSecretshop->refreshedTimes = 0;
  599. req()->userInfo->game->userSecretshop = $userSecretshop;
  600. }
  601. /**
  602. * [8809]【移动支付】购买神秘商城物品
  603. * 规则: 商城物品会刷新
  604. */
  605. public static function m_pay_buyDynamic() {
  606. $user = new Data_UserGame(req()->userInfo->game);
  607. $userSecretshop = new Info_UserSecretshop($user->userSecretshop);
  608. $itemId = req()->paras[0]; # 商品id (点一次购买一个)
  609. $num = 1; # 暂时固定为一次购买一个
  610. #
  611. my_Assert(CommUtil::isPropertyExists($userSecretshop->currentItems, $itemId), ErrCode::pay_secretshop_noitem_err);
  612. $cishu = $userSecretshop->currentItems->$itemId; # 购买次数
  613. my_Assert($cishu < glc()->secretshop_itembuy_maxtimes, ErrCode::pay_secretshop_buytimes); # 判断购买次数
  614. $shopItem = GameConfig::secretshop_typeId_getItem($itemId); # 常量数据
  615. $amt = $shopItem->price * pow(2, $cishu); # 计算价格
  616. switch ($shopItem->pricetype) {
  617. case 1:
  618. my_Assert($user->base()->Consume_Cash($amt), ErrCode::notenough_cash_msg); # 扣除钻石
  619. break;
  620. case 2:
  621. my_Assert($user->base()->Consume_Gold($amt), ErrCode::notenough_gold_msg); # 扣除金币
  622. break;
  623. default :
  624. return Resp::err(ErrCode::pay_m_type_err);
  625. }
  626. // 道具解包/发货
  627. $err = self::expendSecretShopItem($shopItem, $num); # 发放商品
  628. if ($err != ErrCode::ok) { # 发货失败
  629. return Resp::err($err);
  630. }
  631. $userSecretshop->currentItems->$itemId += 1; # 购买次数+1
  632. $user->userSecretshop = $userSecretshop;
  633. req()->userInfo->game = $user;
  634. UserProc::updateUserInfo(); # 回写数据
  635. // StatProc::secretShopbuy($req->zoneid, $req->uid, $itemId, $num); # 统计/监控数据
  636. return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
  637. 'gold' => $user->baseInfo->gold,
  638. 'tili' => $user->baseInfo->tili,
  639. 'cash' => $user->baseInfo->cash,
  640. 'store' => $user->baseInfo->store, # # 背包,(装备、碎片、。。)
  641. 'heros' => $user->baseInfo->heros # # 角色
  642. ));
  643. //
  644. }
  645. /**
  646. *
  647. * @param sm_secretshop $shopItem
  648. * @param type $num
  649. */
  650. private static function expendSecretShopItem($shopItem, $num) {
  651. for ($i = 0; $i < $num; $i++) {
  652. $err = StoreProc::AddMultiItemInStore($shopItem->goods, '神秘商城');
  653. if ($err) {
  654. return $err;
  655. }
  656. }
  657. return ErrCode::ok;
  658. }
  659. /**
  660. * [8807]【移动支付】 购买普通商城物品
  661. */
  662. public static function m_pay() {
  663. $user = req()->userInfo->game; # user引用
  664. my_Assert(count(req()->paras) >= 3, ErrCode::parasnotenough_msg); # 参数不足
  665. list($paytype, $itemId, $num) = req()->paras; # 付费类型, 1.钻石, 2.金币 ,道具ID ,数量, 默认为1
  666. my_Assert($num >= 1, ErrCode::paras_err); # 参数非法,
  667. $shopItem = GameConfig::shop_getItem($itemId); # 取商品的常量数据
  668. my_Assert(isset($shopItem), ErrCode::err_const_no); # 检测是否存在道具的常量数据
  669. my_Assert($shopItem->pricetype == $paytype, ErrCode::pay_price_err); # 商品定价类型检查
  670. $amt = $shopItem->price; # 道具价格(钻石)
  671. my_Assert($amt > 0, ErrCode::pay_price_err); # 商品定价数值检查
  672. $bDeal = false; # 成交标志位
  673. switch ($paytype) { # 1. 钻石, 2. 金币, other:非法
  674. case 1: # 钻石
  675. $bDeal = req()->userInfo->game->base()->Consume_Cash($amt); # 更新(扣除)玩家游戏币(钻石)余额
  676. my_Assert($bDeal, ErrCode::notenough_cash_msg); # 防范扣除失败
  677. break;
  678. case 2: # 金币
  679. $bDeal = $user->base()->Consume_Gold($amt * $num); # 更新玩家金币余额
  680. my_Assert($bDeal, ErrCode::notenough_gold_msg); # 防范扣除失败
  681. break;
  682. default : # 未知的支付类型
  683. return Resp::err(ErrCode::pay_m_type_err);
  684. }
  685. my_Assert($bDeal, ErrCode::err_innerfault); # 交易失败
  686. $err = self::expendShopItem($shopItem, $num); # 发放商品(普通商城只有金币和体力)
  687. my_Assert(ErrCode::ok == $err, $err); # 防范发货失败
  688. UserProc::updateUserInfo(); # 回写数据
  689. // StatProc::shopbuy($zoneid, $uid, $itemId, $num); # 统计/监控数据
  690. return Resp::ok(array(# # 成功后将最新的玩家数据返回给客户端
  691. 'gold' => $user->baseInfo->gold,
  692. 'tili' => $user->baseInfo->tili,
  693. 'cash' => $user->baseInfo->cash,
  694. 'store' => $user->store
  695. ));
  696. }
  697. /**
  698. * 解包商城物品
  699. * @param sm_Shop $shopItem
  700. * @param int $num 数量
  701. */
  702. static function expendShopItem($shopItem, $num) {
  703. for ($i = 0; $i < $num; $i++) {
  704. $err = StoreProc::AddMultiItemInStore($shopItem->goods, '商城');
  705. my_Assert(ErrCode::ok == $err, $err);
  706. }
  707. return ErrCode::ok;
  708. }
  709. // </editor-fold>
  710. //
  711. //
  712. // <editor-fold defaultstate="collapsed" desc=" 支付活动 - 首付礼包">
  713. /**
  714. * [8802] 领取首付礼包
  715. */
  716. public static function m_GetFirstPayGift() {
  717. $itemId = glc()->FirstPay_ItemId;
  718. $privateState = req()->userInfo->game->privateState;
  719. if (CommUtil::isPropertyExists($privateState, "firstPayGift") #
  720. && $privateState->firstPayGift) { # 如果已经领取首付礼包
  721. return Resp::err(ErrCode::pay_firstpaygetted);
  722. }
  723. my_Assert(req()->userInfo->game->baseInfo->charge_amt > 0, ErrCode::pay_firstpayno_err); # 如果尚未完成首付
  724. $itemModel = GameConfig::shop_getItem($itemId); # 取商品常量
  725. if ($itemModel == null) { # 检测首付礼包是否存在
  726. return Resp::err(ErrCode::err_const_no);
  727. }
  728. req()->userInfo->game->privateState->firstPayGift = true; # 设置首付标志
  729. StoreProc::AddMultiItemInStore($itemModel->goods); # 发放首付礼包到玩家仓库
  730. UserProc::updateUserInfo(); # 更新玩家数据
  731. return Resp::ok(array('itemid' => $itemId,
  732. 'rewardstr' => $itemModel->goods,
  733. 'store' => req()->userInfo->game->store)); # 回送成功信息
  734. }
  735. // </editor-fold>
  736. //
  737. //
  738. //
  739. }