Jelajahi Sumber

fix goods price calc

stanley-king 4 tahun lalu
induk
melakukan
6afcc7f920

+ 8 - 2
data/config/dev/vgoods.ini.php

@@ -1,9 +1,15 @@
 <?php
 declare(strict_types=0);
 
-$config['membcard_exclude_goods_id'] = [6217];
+$config['exclude_preferential_goods_ids'] = [6217];
 $config['card_coomonid'] = ['oil' => 3449, 'mobile' => 3450];
-$config['tips'] = ['first_order' => '首次充值立享9.7折', 'vip_first_order' => '会员充值9.5折','none_vip' => '升级会员享受9.5折', 'vip_user' => '分享给好友'];
+
+$config['first_order_scene'] = ['oil' => 3449, 'mobile' => 3450, 'special_id' => 1033];
+
+$config['tips'] =  ['first_order' => '首次充值享受会员价95折',
+                    'vip_first_order' => '会员充值全场95折',
+                    'none_vip' => '邀请好友和升级会员都能享受95折',
+                    'vip_user' => '分享给好友,一起省钱吧~'];
 
 $handlers = [];
 #type:虚拟商品类型,order_method下午单后的自动操作函数,

+ 5 - 2
data/config/prod/vgoods.ini.php

@@ -1,9 +1,12 @@
 <?php
 declare(strict_types=0);
 
-$config['membcard_exclude_goods_id'] = [6217];
+$config['exclude_preferential_goods_ids'] = [6217];
 $config['card_coomonid'] = ['oil' => 3449, 'mobile' => 3450];
-$config['tips'] = ['first_order' => '首次充值立享9.7折', 'vip_first_order' => '会员充值9.5折','none_vip' => '升级会员享受9.5折', 'vip_user' => '分享给好友'];
+$config['tips'] =  ['first_order' => '首次充值享受会员价95折',
+                    'vip_first_order' => '会员充值全场95折',
+                    'none_vip' => '邀请好友和升级会员都能享受95折',
+                    'vip_user' => '分享给好友,一起省钱吧~'];
 
 $handlers = [];
 #type:虚拟商品类型,order_method下午单后的自动操作函数,

+ 12 - 3
data/logic/buy_virtual.logic.php

@@ -5,6 +5,9 @@
  
  */
 defined('InShopNC') or exit('Access Invalid!');
+
+require_once(BASE_HELPER_PATH . '/account_helper.php');
+
 class buy_virtualLogic
 {
     /**
@@ -84,8 +87,8 @@ class buy_virtualLogic
      * @param int $member_id
      * @return array
      */
-    public function buyStep3($post, $member_id) {
-
+    public function buyStep3($post, $member_id,$calc_vorder_amount = null)
+    {
         $result = $this->getBuyStepData($post['goods_id'], $post['quantity'], $member_id);
         if (!$result['state']) return $result;
         
@@ -93,7 +96,13 @@ class buy_virtualLogic
         $member_info = $result['data']['member_info'];
 
         //应付总金额计算
-        $pay_total = $goods_info['goods_price'] * $goods_info['quantity'];
+        if(empty($calc_vorder_amount)) {
+            $pay_total = $goods_info['goods_price'] * $goods_info['quantity'];
+        }
+        else {
+            $pay_total = call_user_func($calc_vorder_amount,$goods_info);
+        }
+
         $store_id = $goods_info['store_id'];
         $store_goods_total_list = [$store_id => $pay_total];
         $pay_total = $store_goods_total_list[$store_id];

+ 1 - 1
helper/account_helper.php

@@ -45,7 +45,7 @@ require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
 
 class account_helper
 {
-    public static function calc_goods_price($goods,$userid)
+    public static function calc_vorder_amount($goods_info,$userid)
     {
 
     }

+ 11 - 10
helper/bonus/RateMoney.php

@@ -33,7 +33,7 @@ class RateMoney implements IMoneyCalc
     public function add_bonuses($items)
     {
         foreach ($items as $item) {
-            $bonus = \bonus\user_bonus::create_by_param($item);
+            $bonus = user_bonus::create_by_param($item);
             $rate = $bonus->bonus_rate();
             $amount = intval($bonus->remain_amount() * 100 + 0.5);
 
@@ -56,21 +56,22 @@ class RateMoney implements IMoneyCalc
     public function is_enough(&$rate, $amount)
     {
         $amount = intval($amount * 100 + 0.5);
-        foreach ($this->mRates as $key => $val) {
+        foreach ($this->mRates as $key => $val)
+        {
             $val = intval($val * 100 + 0.5);
             if ($rate == -1) {
                 if ($val >= $amount) {
                     $rate = $key;
                     return true;
                 }
-            } else {
-                if ($rate == $key) {
-                    $rate = $key;
-                    if ($val >= $amount) {
-                        return true;
-                    } else {
-                        return false;
-                    }
+            }
+            elseif ($rate == $key)
+            {
+                $rate = $key;
+                if ($val >= $amount) {
+                    return true;
+                } else {
+                    return false;
                 }
             }
         }

+ 216 - 0
helper/calc_helper.php

@@ -0,0 +1,216 @@
+<?php
+declare(strict_types=0);
+
+require_once (BASE_HELPER_PATH . '/model/member_info.php');
+
+use mcard\user_mcards;
+
+interface ICalc
+{
+    public function calc_vgoods_price($goods_info);
+    public function calc_vorder_amount($order_info);
+    public function calc_tips();
+}
+
+class CalcPrice implements ICalc
+{
+    private const FIRST_ORDER_PRICE   = 0.95;
+    private const DEFAULT_ORDER_PRICE = 0.99;
+    private const STEP_PRICE_ITEMS = [
+        ['num' => 10, 'discount' => 0.95,'tip' => '邀请10人可享95折扣'],
+        ['num' => 5, 'discount' => 0.96,'tip' => '邀请5人可享96折扣'],
+        ['num' => 3, 'discount' => 0.97,'tip' => '邀请3人可享97折扣']
+    ];
+
+    private $mUserId;
+    private $mUserCards = null;
+    private $mMemberInfo = null;
+    private $mInvitees = 0;
+
+    private $mUsedInvitees = false;
+    private $mUsedInviteesNum = 0;
+
+    public function __construct($userid)
+    {
+        $this->mUserId = intval($userid);
+        if($userid > 0) {
+            $this->mUserCards = new user_mcards($userid);
+            $this->mMemberInfo = new member_info($userid);
+            $this->mInvitees = $this->invitees();
+        }
+    }
+
+    private function isVip()
+    {
+        if($this->mUserId > 0 && $this->mUserCards != null) {
+            return $this->mUserCards->hasCards();
+        }
+        else {
+            return false;
+        }
+    }
+
+    private function isFirstorOrder()
+    {
+        if($this->mUserId > 0 && $this->mMemberInfo != null) {
+            return $this->mMemberInfo->order_num() == 0;
+        }
+        else {
+            return true;
+        }
+    }
+
+    private function select_invitees()
+    {
+        if($this->mUserId <= 0 || $this->mMemberInfo == null) {
+            return false;
+        }
+
+        $left_invitees = $this->mInvitees - $this->mMemberInfo->used_invitees();
+
+        foreach (self::STEP_PRICE_ITEMS as $item) {
+            $num = $item['num'];
+            if($left_invitees >=  $num) {
+                return $item;
+            }
+        }
+
+        return false;
+    }
+
+    private function invitees()
+    {
+        $model = model('member');
+        $ret = $model->field('count(*) inviter_count' )->where(['inviter_id' => $this->mUserId])->select();
+        if(empty($ret)) {
+            return 0;
+        }
+        else {
+            return intval($ret[0]['inviter_count']);
+        }
+    }
+
+    private function isExcluded($goods_id)
+    {
+        global $config;
+        $exclue_gids = $config['exclude_preferential_goods_ids'];
+
+        if(empty($exclue_gids)) {
+            return false;
+        } else {
+            return in_array(intval($goods_id),$exclue_gids);
+        }
+    }
+
+    public function deduct_invitees()
+    {
+        if($this->mUsedInvitees) {
+            $model = model('member');
+            $num = $this->mUsedInviteesNum;
+            $model->editMember(['member_id' => $this->mUserId], ['used_invitees'=> ['exp', "used_invitees+{$num}"]]);
+        }
+    }
+
+    public function calc_tips()
+    {
+        global $config;
+
+        if($this->mUserId <= 0) {
+            return $config['tips']['first_order'];
+        }
+
+        $fVip = $this->isVip();
+        if($fVip)
+        {
+            if(session_helper::first_order()) {
+                $tips = $config['tips']['vip_first_order'];
+            } else {
+                $tips = $config['tips']['vip_user'];
+            }
+        }
+        elseif(session_helper::first_order()) {
+            $tips = $config['tips']['first_order'];
+        } else {
+            $tips = $config['tips']['none_vip'];
+        }
+
+        return $tips;
+    }
+
+    public function inviter_tips()
+    {
+        if(!$this->mUsedInvitees) return '';
+
+        $left_invitees = $this->mInvitees - $this->mMemberInfo->used_invitees();
+
+        $cur = [];
+        $next = [];
+        foreach (self::STEP_PRICE_ITEMS as $item)
+        {
+            $num = $item['num'];
+            if($left_invitees >= $num) {
+                $cur = $item;
+            } else {
+                $next = $item;
+            }
+        }
+        $count = $next['num'] - $left_invitees;
+        $discount = $next['discount'] * 100;
+
+        $tip = "再邀请{$count}人,可享受{$discount}折扣";
+
+        return $tip;
+    }
+
+    public function calc_vgoods_price($goods_info)
+    {
+        $goods_id = intval($goods_info['goods_id']);
+        $goods_price = $goods_info['goods_price'];
+
+        if($this->isExcluded($goods_id)) {
+            return ['price_des' => '售价', 'accu_price' => round($goods_price,2)];
+        }
+        elseif($this->isVip()) {
+            $price = $this->mUserCards->calc_price($goods_id, $goods_price);
+            return ['price_des' => '会员价', 'accu_price' => round($price,2)];
+        }
+        elseif($this->isFirstorOrder()) {
+            return ['price_des' => '首单价', 'accu_price' => round($goods_price * self::FIRST_ORDER_PRICE,2)];
+        }
+        elseif(!empty($num_dis = $this->select_invitees())) {
+            $num = $num_dis['num'];
+            $this->mUsedInvitees = true;
+            $discount = $num_dis['discount'];
+            return ['price_des' => '邀请价', 'accu_price' => round($goods_price * $discount,2)];
+        }
+        else {
+            return ['price_des' => '售价', 'accu_price' => round($goods_price * self::DEFAULT_ORDER_PRICE,2)];
+        }
+    }
+
+    public function calc_vorder_amount($goods_info)
+    {
+        $goods_id = intval($goods_info['goods_id']);
+        $goods_price = $goods_info['goods_price'];
+        $num = $goods_info['quantity'];
+
+        if($this->isExcluded($goods_id)) {
+            return round($goods_price * $num,2);
+        }
+        elseif($this->isVip()) {
+            return $this->mUserCards->calc_amount($goods_id, $goods_price);
+        }
+        elseif($this->isFirstorOrder()) {
+            return round($goods_price * self::FIRST_ORDER_PRICE * $num,2);
+        }
+        elseif(!empty($num_dis = $this->select_invitees())) {
+            $num = $num_dis['num'];
+            $this->mUsedInvitees = true;
+            $discount = $num_dis['discount'];
+            return round($goods_price * $discount * $num);
+        }
+        else {
+            return round($goods_price * $num * self::DEFAULT_ORDER_PRICE,2);
+        }
+    }
+}

+ 4 - 7
helper/goods_helper.php

@@ -95,7 +95,7 @@ class goods_helper
         $mod = Model('goods');
         $goods_list = $mod->getGoodsListByColorDistinct(['goods_commonid' => ['in', $common_ids]],self::fieldstr);
 
-        $goods_ids = array();
+        $goods_ids = [];
         foreach ($goods_list as $goods) {
             $goods_ids[] = intval($goods['goods_id']);
         }
@@ -105,7 +105,7 @@ class goods_helper
     public function online_summary(&$goods_ids, &$related_goods)
     {
         $goods_list = Model('goods')->cls()->getGoodsOnlineList(['goods_id' => ['in', $goods_ids]],self::fieldstr);
-        $goods_ids = array();
+        $goods_ids = [];
         foreach ($goods_list as $goods) {
             $goods_id = intval($goods['goods_id']);
             $goods_ids[] = $goods_id;
@@ -121,7 +121,7 @@ class goods_helper
         return $this->summary($goods_list,$related_goods);
     }
 
-    public function summary($goods_list, &$related_goods)
+    public function summary($goods_list, &$related_goods,$vgoods_price_calc = null)
     {
         $related_goods = [];
         $summary_list = [];
@@ -132,7 +132,7 @@ class goods_helper
         foreach ($goods_list as $goods)
         {
             $summary = new goods_summary($this->mPriceCalcer,$goods);
-            $info = $summary->format($act_type,$act_id,$favorate,$anotice,$this->mUseMainPage);
+            $info = $summary->format($act_type,$act_id,$favorate,$anotice,$this->mUseMainPage,$vgoods_price_calc);
             $goods_id = intval($goods['goods_id']);
             $sort_summarys[$goods_id] = $info;
 
@@ -164,9 +164,6 @@ class goods_helper
                     $ltimes[$act_id] = $info;
                 }
             }
-            else {
-
-            }
 
             $have_bundle = $summary['have_bundle'];
             if($have_bundle)

+ 1 - 1
helper/mcard/mcard.php

@@ -46,7 +46,7 @@ function isVip($member_id)
 function canUseVip($goods_id)
 {
     global $config;
-    $exclue_gids = $config['membcard_exclude_goods_id'];
+    $exclue_gids = $config['exclude_preferential_goods_ids'];
     if(empty($exclue_gids)) {
         return true;
     } else {

+ 10 - 2
helper/mcard/user_mcards.php

@@ -151,13 +151,21 @@ class user_mcards
     public function calc_price($goods_id,$price)
     {
         if(canUseVip($goods_id)) {
-            return $this->calc_amount($price);
+            return $this->_calc_amount($price);
         } else {
             return $price;
         }
     }
+    public function calc_amount($goods_id,$amount)
+    {
+        if(canUseVip($goods_id)) {
+            return $this->_calc_amount($amount);
+        } else {
+            return $amount;
+        }
+    }
 
-    public function calc_amount($amount)
+    private function _calc_amount($amount)
     {
         if($this->enough($amount))
         {

+ 12 - 3
helper/model/goods_summary.php

@@ -8,6 +8,8 @@
  */
 
 require_once (BASE_ROOT_PATH . '/helper/user_session/fcode.php');
+require_once(BASE_HELPER_PATH . '/account_helper.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
 
 class goods_summary
 {
@@ -79,7 +81,7 @@ class goods_summary
         return ($add_time > $start);
     }
 
-    public function format(&$act_type, &$act_id, user_session\favorite $favorate, user_session\anotice $anotice, $main_image)
+    public function format(&$act_type, &$act_id, user_session\favorite $favorate, user_session\anotice $anotice, $main_image,$vgoods_price_calc = null)
     {
         $summary = [];
 
@@ -210,9 +212,16 @@ class goods_summary
             $summary['gap_show'] = false;
             $summary['gap_desc'] = "";
         }
+        if(!empty($vgoods_price_calc)) {
+            $params = call_user_func($vgoods_price_calc,$this->goods_info);
+            foreach ($params as $key => $val) {
+                $summary[$key] = $val;
+            }
+        }
+
         $summary['earn_bonus'] = $config['bonus_gap']['earn_bonus'];
-        $summary['favored']  = $favorate->favored_goods($this->goods_id);
-        $summary['anoticed'] = $anotice->noticed($this->goods_id);
+        $summary['favored']    = $favorate->favored_goods($this->goods_id);
+        $summary['anoticed']   = $anotice->noticed($this->goods_id);
 
         if($is_virtual) {
             $op_info = false;

+ 3 - 0
helper/model/member_info.php

@@ -175,6 +175,9 @@ class member_info
     public function inviter_id() {
         return intval($this->member_info['inviter_id']);
     }
+    public function used_invitees() {
+        return intval($this->member_info['used_invitees']);
+    }
 
     public function can_sms() {
         $logtm = intval($this->member_info['member_login_time']);

+ 16 - 39
mobile/control/index.php

@@ -26,6 +26,8 @@ require_once(BASE_HELPER_PATH . '/room/tpl_group_home.php');
 require_once(BASE_HELPER_PATH . '/room/tpl_chatwo_home.php');
 require_once(BASE_HELPER_PATH . '/mcard/mcard.php');
 require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
+
 
 class indexControl extends specialControl
 {
@@ -36,6 +38,12 @@ class indexControl extends specialControl
         parent::__construct();
     }
 
+    public function mini_indexOp()
+    {
+        $_GET['special_id'] = 0;
+        return parent::indexOp();
+    }
+
     public function tabsOp()
     {
         $client_tpe = session_helper::client_type();
@@ -162,55 +170,32 @@ class indexControl extends specialControl
     ///获取充值卡的数据接口.
     public function card_goodsOp()
     {
-        global $config;
         $page_type = $_GET['page_type']; //oil or phone page.
         if(empty($page_type)) {
             return self::outerr(errcode::ErrParamter);
         }
 
-        $goods = $this->card_goods($page_type);
-        $fVip = mcard\isVip(session_helper::memberid());
+        $calctor = new CalcPrice(session_helper::memberid());
+        $goods = $this->card_goods($page_type,$calctor);
         $ret = [];
 
-        $discount = 0.0;
         if(session_helper::memberid() > 0)
         {
             $card_list =  mtopcard\priority_cards(session_helper::memberid(),$page_type);
             $ret['cards'] = mtopcard\topcard_format($card_list);
-            if($fVip)
-            {
-                if(session_helper::first_order()) {
-                    $ret['tips'] = $config['tips']['vip_first_order'];
-                } else {
-                    $ret['tips'] = $config['tips']['vip_user'];
-                }
-            }
-            else{
-                $ret['tips'] = $config['tips']['none_vip'];
-            }
         }
         else {
-            $ret['tips'] = $config['tips']['first_order'];
             $ret['cards'] = [];
-            $discount = 0.02;
-        }
-
-        if(session_helper::first_order()) {
-            $discount = 0.02;
         }
 
+        $ret['tips'] = $calctor->calc_tips();
+        $ret['inviter_tips'] = $calctor->inviter_tips();
 
-        if($fVip) {
-            mcard\vip_price($goods,session_helper::memberid());
-        } else {
-            mcard\firorder_price($goods,$discount);
-        }
         $ret['goods'] = $goods;
-
         return self::outsuccess($ret);
     }
 
-    private function card_goods($card_type)
+    private function card_goods($card_type,$calctor)
     {
         global $config;
         $card_commids = $config['card_coomonid'];
@@ -224,20 +209,12 @@ class indexControl extends specialControl
             $mod_goods = Model('goods');
             $goods_list = $mod_goods->getGoodsOnlineList(['goods_commonid' => $commonid]);
             $helper = new goods_helper(new bonus\normal_calc());
-            $goods_list = $helper->summary($goods_list, $related_goods);
+            $goods_list = $helper->summary($goods_list, $related_goods,[$calctor,'calc_vgoods_price']);
 
             $summarys = &$goods_list['summary'];
-            $ret = [];
-            foreach ($summarys as $summary)
-            {
-                $item['goods_spec'] = $summary['goods_spec'];
-                $item['goods_id'] = $summary['goods_id'];
-                $item['goods_price'] = $summary['goods_price'];
-                $ret[] = $item;
-            }
-            usort($ret,[__CLASS__,'comp_goods']);
+            usort($summarys,[__CLASS__,'comp_goods']);
 
-            return $ret;
+            return $summarys;
         }
         else {
             return [];

+ 6 - 1
mobile/control/member_buy.php

@@ -18,6 +18,8 @@ require_once(BASE_HELPER_PATH . '/pay_helper.php');
 require_once(BASE_HELPER_PATH . '/fcode/operator.php');
 require_once(BASE_HELPER_PATH . '/fcode/send_manager.php');
 require_once(BASE_HELPER_PATH . '/user_session/fcode.php');
+require_once(BASE_HELPER_PATH . '/calc_helper.php');
+
 
 class member_buyControl extends mbMemberControl
 {
@@ -218,12 +220,15 @@ class member_buyControl extends mbMemberControl
         }
 
         $input['order_from'] = 2;
-        $result = $logic_buy_virtual->buyStep3($input, session_helper::memberid());
+        $calctor = new CalcPrice(session_helper::memberid());
+        $result = $logic_buy_virtual->buyStep3($input, session_helper::memberid(),[$calctor,'calc_vorder_amount']);
         if (!$result['state']) {
             return self::outerr(errcode::ErrOrder, $result['msg']);
         }
         else
         {
+            $calctor->deduct_invitees();
+
             $payment = $_POST['payment'];
             $order_sn = $result['data']['order_sn'];
 

+ 6 - 6
mobile/control/member_vorder.php

@@ -121,12 +121,12 @@ class member_vorderControl extends mbMemberControl
         if(empty($order_sn)) {
             return self::outerr(errcode::ErrParamter);
         }
-        $order = $this->get_order(array("buyer_id" => session_helper::memberid(),'order_sn' => $order_sn));
+        $order = $this->get_order(["buyer_id" => session_helper::memberid(),'order_sn' => $order_sn]);
         $pay_ments = pay_helper::pay_types();
         if($order == false) {
             return self::outerr(errcode::ErrOrder);
         } else {
-            return self::outsuccess(array('order' => $order,"paytype" => $pay_ments));
+            return self::outsuccess(['order' => $order,"paytype" => $pay_ments]);
         }
     }
 
@@ -157,20 +157,20 @@ class member_vorderControl extends mbMemberControl
             output_error('订单不存在');
         }
         $model_vr_order = Model('vr_order');
-        $condition = array();
+        $condition = [];
         $condition['order_id'] = $order_id;
         $condition['buyer_id'] = session_helper::memberid();
         $order_info = $model_vr_order->getOrderInfo($condition);
         if (empty($order_info) || $order_info['delete_state'] == ORDER_DEL_STATE_DROP) {
             output_error('订单不存在');
         }
-        $order_list = array();
+        $order_list = [];
         $order_list[$order_id] = $order_info;
         $order_list = $model_vr_order->getCodeRefundList($order_list);//没有使用的兑换码列表
-        $code_list = array();
+        $code_list = [];
         if(!empty($order_list[$order_id]['code_list'])) {
             foreach ($order_list[$order_id]['code_list'] as $value) {
-                $code = array();
+                $code = [];
                 $code['vr_code'] = $value['vr_code'];
                 $code['vr_indate'] = $value['vr_indate'];
                 $code_list[] = $code;

+ 1 - 0
mobile/index.php

@@ -6,6 +6,7 @@
  */
 
 define('APP_ID','mobile');
+
 define('BASE_PATH',str_replace('\\','/',dirname(__FILE__)));
 
 ////框架扩展