• php抢购秒杀逻辑


    转载 原地址:https://www.tongpankt.com/7286

      1 <?php
      2 /**
      3  * 抢购的处理逻辑
      4  */
      5 
      6 include 'init.php';
      7 
      8 $TEMPLATE['type'] = 'buy';
      9 $TEMPLATE['pageTitle'] = '抢购';
     10 
     11 $active_model = new modelActive();
     12 $goods_model = new modelGoods();
     13 
     14 // 参数的处理
     15 $active_id = getReqInt('active_id');
     16 $goods_id = getReqInt('goods_id');
     17 $goods_num = getReqInt('goods_num');
     18 $sign_data = $_POST['sign_data'];
     19 $question_sign = $_POST['question_sign'];
     20 $ask = $_POST['ask'];
     21 $answer = $_POST['answer'];
     22 $action = isset($_POST['action']) ? $_POST['action'] : false;
     23 
     24 if ('buy_cart' == $action) {
     25     $goods_num = $_POST['num'][0];
     26 }
     27 $client_ip = getClientIp();
     28 
     29 // 1 验证用户是否登录
     30 if (!$login_userinfo || !$login_userinfo['uid']) {
     31     $result = array('error_no' => '101', 'error_msg' => '用户登录之后才可以参与');
     32     show_result($result);
     33 }
     34 $uid = $login_userinfo['uid'];
     35 $username = $login_userinfo['username'];
     36 // 2 验证参数是否正确、合法
     37 if (!$active_id || !$goods_id
     38     || !$goods_num || !$question_sign) {
     39     $result = array('error_no' => '102', 'error_msg' => '参数提交异常');
     40     show_result($result);
     41 }
     42 // 3.1 验证活动状态信息
     43 $status_check = false;
     44 $str_sign_data = unsignQuestion($sign_data);
     45 $sign_data_info = json_decode($str_sign_data, true);
     46 // 时间不能超过当前时间5分钟,IP和用户保持不变
     47 if ($sign_data_info
     48     && $sign_data_info['now'] < $now
     49     && $sign_data_info['now'] > $now - 300
     50     && $sign_data_info['ip'] == $client_ip
     51     && $sign_data_info['uid'] == $uid
     52 ) {
     53     $status_check = true;
     54 }
     55 if (!$status_check) {
     56     $result = array('error_no' => '103', 'error_msg' => '用户校验值验证没有通过');
     57     show_result($result);
     58 }
     59 // 3.2 验证问答信息是否正确
     60 $question_check = false;
     61 $str_question = unsignQuestion($question_sign);
     62 $question_info = json_decode(trim($str_question), true);
     63 if ($str_question && $question_info) {
     64     if ($question_info['ask'] == $ask
     65         && $question_info['answer'] == $answer
     66         && $question_info['aid'] == $active_id
     67         && $question_info['uid'] == $uid
     68         && $question_info['ip'] == $client_ip
     69         && $question_info['now'] > $now -300
     70     ) {
     71         $question_check = true;
     72     }
     73 }
     74 if (!$question_check) {
     75     $result = array('error_no' => '103', 'error_msg' => '问答验证没有通过');
     76     show_result($result);
     77 }
     78 
     79 // 统一格式化单商品、组合商品的数据结构
     80 $nums = $goods = array();
     81 if ('buy_cart' != $action) {
     82     $nums = array($goods_num);
     83     $goods = array($goods_id);
     84 } else {
     85     $num = $_POST['num'];
     86     $goods = $_POST['goods'];
     87 }
     88 
     89 $redis_obj = commonDatasource::getRedis('instance1');
     90 $d_list = array(
     91     'u_trade_' . $uid . '_' . $active_id,
     92     'st_a_' . $active_id
     93 );
     94 /**
     95  * id, sys_status,
     96  * num_user, num_left,
     97  * price_normal, price_discount
     98  */
     99 foreach ($goods as $i => $goods_id) {
    100     $d_list[] = 'info_g_' . $goods_id;  // 商品详情
    101 }
    102 $data_list = $redis_obj->mget($d_list);
    103 // 4 验证用户是否已经购买
    104 if ($data_list[0]) {
    105     $result = array('error_no' => '104', 'error_msg' => '请不要重复提交订单');
    106     show_result($result);
    107 }
    108 // 5 验证活动信息,商品信息是否正常
    109 if ($data_list[1]) {
    110     $result = array('error_no' => '105', 'error_msg' => '活动信息异常');
    111     show_result($result);
    112 }
    113 unset($data_list[0]);
    114 unset($data_list[1]);
    115 /*
    116 // 4 验证用户是否已经购买
    117 $trade_model = new modelTrade();
    118 $trade_info = $trade_model->getUserTrade($uid, $active_id);
    119 if ($trade_info) {
    120     $result = array('error_no' => '104', 'error_msg' => '请不要重复提交订单');
    121     show_result($result);
    122 }
    123 // 5 验证活动信息,商品信息是否正常
    124 $active_info = $active_model->get($active_id);
    125 if (!$active_info || $active_info['sys_status'] !== '1'
    126     || $active_info['time_begin'] > $now
    127     || $active_info['time_end'] < $now
    128 ) {
    129     $result = array('error_no' => '105', 'error_msg' => '活动信息异常');
    130     show_result($result);
    131 }
    132 if ('buy_cart' != $action) {
    133     $nums = array($goods_num);
    134     $goods = array($goods_id);
    135 } else {
    136     $nums = $_POST['num'];
    137     $goods = $_POST['goods'];
    138 }
    139 */
    140 $num_total = $price_total = $price_discount = 0;
    141 $trade_goods = array();
    142 foreach ($data_list as $i => $goods_info) {
    143     $goods_num = $nums[$i - 2];
    144 //    $goods_info = $goods_model->get($goods_id);
    145     if (!$goods_info || $goods_info['sys_status'] !== '1') {
    146         $result = array('error_no' => '106', 'error_msg' => '商品信息异常');
    147         show_result($result);
    148     }
    149 // 6 验证用户购买的商品数量是否在限制的范围内
    150     if ($goods_num > $goods_info['num_user']) {
    151         $result = array('error_no' => '107', 'error_msg' => '超出商品数量的限制');
    152         show_result($result);
    153     }
    154 // 7 验证商品是否还有剩余数量
    155     if ($goods_info['num_left'] < $goods_num) {
    156         $result = array('error_no' => '108', 'error_msg' => '商品剩余数量不足');
    157         show_result($result);
    158     }
    159 // 8 扣除商品剩余数量
    160     $left = $goods_model->changeLeftNumCached($goods_id, 0-$goods_num);
    161     $ok = false;
    162     if ($left >= 0) {
    163         $ok = $goods_model->changeLeftNum($goods_id, 0-$goods_num);
    164     } else {
    165         // 扣除商品库存失败
    166         $goods_model->changeStatusCached($goods_id, 0);
    167         $result = array('error_no' => '108', 'error_msg' => '商品剩余数量不足');
    168         show_result($result);
    169     }
    170 
    171 
    172 // 9.1 创建订单信息,订单的商品信息
    173     $trade_goods[] = array(
    174         'goods_info' => $goods_info,
    175         'goods_num' => $goods_num
    176     );
    177     $num_total += $goods_num;
    178     $price_total += $goods_info['price_normal'] * $goods_num;
    179     $price_discount += $goods_info['price_discount'] * $goods_num;
    180 }
    181 // 9.2 保存订单信息
    182 $trade_model = new modelTrade();
    183 $trade_info = array(
    184     'active_id' => $active_id,
    185     'goods_id' => $goods_id,
    186     'num_total' => $num_total,
    187     'num_goods' => count($goods),
    188     'price_total' => $price_total,
    189     'price_discount' => $price_discount,
    190     'goods_info' => json_encode($trade_goods),
    191     'uid' => $uid,
    192     'username' => $username,
    193     'sys_ip' => $client_ip,
    194     'sys_dateline' => $now,
    195     'time_confirm' => $now,
    196     'sys_status' => 1,
    197 );
    198 foreach ($trade_info as $k => $v) {
    199     $trade_model->$k = $v;
    200 }
    201 $trade_id = $trade_model->create();
    202 if ($trade_id) {
    203     $redis_obj->set('u_trade_' . $uid . '_' . $active_id, 1, 86400);
    204 }
    205 
    206 // 10 返回提示信息
    207 $result = '秒杀成功,请尽快去支付';
    208 show_result($result, '/trade.php');
  • 相关阅读:
    RabbitMQ——CLI 管理工具 rabbitmqadmin
    RabbitMQ——Fedration插件
    RabbitMQ——使用Shovel插件迁移数据
    Http——HttpClient使用
    Http——Keep-Alive机制
    Http——HttpURLConnection详解
    Kafak——日志数据策略
    Keepalived + LVS 搭建高可用负载均衡
    TCP——抓包分析
    常见的网络端口
  • 原文地址:https://www.cnblogs.com/sakura10032/p/9994182.html
Copyright © 2020-2023  润新知