作为一个开发软件的程序员来说,要开发系统必先整理好产品需求,产品功能分析先行,站在商业模式角度来说,好的软件系统必须符合产品设计理念,产品的流量要以用户用户自驱,趣味性,奖励性,激励性的行为去展开,在开发惠乐优选系统的过程中,产品功能要点总结如下,欢迎大家探讨交流,微信号:toudouge
下面我从3个部分来说明惠乐优选系统的开发情况
一、会员功能介绍
二、激励奖励机制介绍
三、系统核心源码分享
一、系统的会员功能介绍
会员拼团行为设计
1.每个账号每天每个分类可以参与拼团20次
2.20人参与拼团,其中只有1人拼中
3.拼团人数满人既开团,60分钟不满人拼团解散,不满人数时拼团解散不扣当日拼团次数
4.根据每个商品设定的拼团人数,其中拼中者获得拼团商品,同类商品累积拼中5次,可以选择其中4件寄售,选择其中1件商品发货自用,拼不中退款,所有参加拼团的拼中或拼不中都可领取1个0.1元到3元的随机现金红包,收益部分T+0结算提现,10元起提(提现手续费6%)
5.SVIP补贴拼团1次,享受自动拼团,尊享会员是身份(普通会员可参团20次,SVIP会员可以开团21次)
6.前期开设5个专区,每个专区每天最多20次拼团收益;五个专区每天一共能拼100次(每团20人开团),每次拼团无论拼中与否,都有一个对应的红包奖励,最低门槛30元既可参团(中5次可寄售4件发货一件),红包金额0.1到3元不等
二、激励奖励机制介绍
奖金驱动设计
1.推荐奖
自邀首单5%现金奖励(实时到账,可提现)
2.晋升制度:
LV1:直推5个有效,好友红包收益的5%,团队红包收益2%,LV2:直推10个有效且团队30个有效,好友红包收益的10%,团队红包收益3%,LV3:直推30个有效且团队80个有效,好友红包收益的15%,团队红包收益4%,平级收益10%,LV2:直推50个有效且团队600个有效,好友红包收益的20%,团队红包收益5%,平级收益10%
3.奖金池分红设计
每拼中1单拿出拼中金额的5%进入排行榜奖金池,当日直邀有效会员人数前10名会员按照比例来分红
分红比例:
第1名30%,第2名18%,第3名12%,第4名8%,第5名7%,第6名6%,第7名6%,第8名5%,第9名5%,第10名3%;每天23点分红,分红结束奖金池清零,次日继续累积奖金池金额
三、系统部分核心源码分享
以下是系统分润核心源码
/** * 程序 李铁牛 15889726201 * 拼团处理 * @param $cartInfo * @return array */ public static function getCombinationOrderPriceGroup($cartInfo) { $storePostage = floatval(sys_config('store_postage')) ?: 0; $storeFreePostage = floatval(sys_config('store_free_postage')) ?: 0; $totalPrice = self::getCombinationOrderTotalPrice($cartInfo); $costPrice = self::getCombinationOrderTotalPrice($cartInfo); if (!$storeFreePostage) { $storePostage = 0; } else { foreach ($cartInfo as $cart) { if (!StoreCombination::where('id', $cart['combination_id'])->value('is_postage')) $storePostage = bcadd($storePostage, StoreCombination::where('id', $cart['combination_id'])->value('postage'), 2); } if ($storeFreePostage <= $totalPrice) $storePostage = 0; } return compact('storePostage', 'storeFreePostage', 'totalPrice', 'costPrice'); } /** * 拼团价格 * @param $cartInfo * @return float */ public static function getCombinationOrderTotalPrice($cartInfo) { $totalPrice = 0; foreach ($cartInfo as $cart) { if ($cart['combination_id']) { $totalPrice = bcadd($totalPrice, bcmul($cart['cart_num'], StoreCombination::where('id', $cart['combination_id'])->value('price'), 2), 2); } } return (float)$totalPrice; } /** * 缓存订单信息 * @param $uid * @param $cartInfo * @param $priceGroup * @param array $other * @param int $cacheTime * @return string * @throws PsrSimpleCacheInvalidArgumentException */ public static function cacheOrderInfo($uid, $cartInfo, $priceGroup, $other = [], $cacheTime = 600) { $key = md5(time()); Cache::set('user_order_' . $uid . $key, compact('cartInfo', 'priceGroup', 'other'), $cacheTime); return $key; } /** * 获取订单缓存信息 * @param $uid * @param $key * @return mixed|null * @throws PsrSimpleCacheInvalidArgumentException */ public static function getCacheOrderInfo($uid, $key) { $cacheName = 'user_order_' . $uid . $key; if (!Cache::has($cacheName)) return null; return Cache::get($cacheName); } /** * 删除订单缓存 * @param $uid * @param $key */ public static function clearCacheOrderInfo($uid, $key) { Cache::delete('user_order_' . $uid . $key); } /** * 生成订单 * @param $uid * @param $key * @param $addressId * @param $payType * @param bool $useIntegral * @param int $couponId * @param string $mark * @param int $combinationId * @param int $pinkId * @param int $seckill_id * @param int $bargain_id * @param bool $test * @param int $isChannel * @param int $shipping_type * @param string $real_name * @param string $phone * @return StoreOrder|bool| hinkModel * @throws hinkException * @throws hinkdbexceptionDataNotFoundException * @throws hinkdbexceptionModelNotFoundException * @throws hinkexceptionDbException */ public static function cacheKeyCreateOrder($uid, $key, $addressId, $payType, $useIntegral = false, $couponId = 0, $mark = '', $combinationId = 0, $pinkId = 0, $seckill_id = 0, $bargain_id = 0, $test = false, $isChannel = 0, $shipping_type = 1, $real_name = '', $phone = '', $storeId = 0, $is_auto = 0) { self::beginTrans(); try { $shipping_type = (int)$shipping_type; $offlinePayStatus = (int)sys_config('offline_pay_status') ?? (int)2; if ($offlinePayStatus == 2) unset(self::$payType['offline']); if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!', true); if (self::be(['unique' => $key, 'uid' => $uid])) return self::setErrorInfo('请勿重复提交订单', true); $userInfo = User::getUserInfo($uid); if (!$userInfo) return self::setErrorInfo('用户不存在!', true); $cartGroup = self::getCacheOrderInfo($uid, $key); if (!$cartGroup) return self::setErrorInfo('订单已过期,请刷新当前页面!', true); $cartInfo = $cartGroup['cartInfo']; $check_hour = intval(date('H')); //$check_goods_info = StoreProduct::field('start_hour,stop_hour')->where('id',$cartInfo[0]['productInfo']['id'])->find()->toArray(); if( $check_hour < 6 || $check_hour >= 22 ) return self::setErrorInfo('还未到该团参与的时间', true); if( StoreOrderSpell::where('uid="'.$uid.'" AND goods_id = "'.$cartInfo[0]['productInfo']['id'].'" AND is_pay = 1 AND status = 0')->count() > 0 ) return self::setErrorInfo('您已经在队列中,请勿重复参加!', true); $priceGroup = $cartGroup['priceGroup']; $other = $cartGroup['other']; $payPrice = (float)$priceGroup['totalPrice']; $addr = UserAddress::where('uid', $uid)->where('id', $addressId)->find(); if ($payType == 'offline' && sys_config('offline_postage') == 1) { $payPostage = 0; } else { $payPostage = self::getOrderPriceGroup($cartInfo, $addr)['storePostage']; } if ($shipping_type === 1) { if (!$test && !$addressId) return self::setErrorInfo('请选择收货地址!', true); if (!$test && (!UserAddress::be(['uid' => $uid, 'id' => $addressId, 'is_del' => 0]) || !($addressInfo = UserAddress::find($addressId)))) return self::setErrorInfo('地址选择有误!', true); } else { if ((!$real_name || !$phone) && !$test) return self::setErrorInfo('请填写姓名和电话', true); $addressInfo['real_name'] = $real_name; $addressInfo['phone'] = $phone; $addressInfo['province'] = ''; $addressInfo['city'] = ''; $addressInfo['district'] = ''; $addressInfo['detail'] = ''; } $cartIds = []; $totalNum = 0; $gainIntegral = 0; foreach ($cartInfo as $cart){ if (!$test && !self::checkProductStock($uid, $cart['product_id'], $cart['cart_num'], $cart['product_attr_unique'], $cart['combination_id'], $cart['seckill_id'], $cart['bargain_id'])) { return false; } $cartIds[] = $cart['id']; $totalNum += $cart['cart_num']; if (!$seckill_id) $seckill_id = $cart['seckill_id']; if (!$bargain_id) $bargain_id = $cart['bargain_id']; if (!$combinationId) $combinationId = $cart['combination_id']; $cartInfoGainIntegral = isset($cart['productInfo']['give_integral']) ? bcmul($cart['cart_num'], $cart['productInfo']['give_integral'], 2) : 0; $gainIntegral = bcadd($gainIntegral, $cartInfoGainIntegral, 2); } $deduction = $seckill_id || $bargain_id || $combinationId; if ($deduction) { $couponId = 0; $useIntegral = false; if (!$test) { unset(self::$payType['offline']); if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('营销产品不能使用线下支付!', true); } } //使用优惠劵 $res1 = true; if ($couponId) { $couponInfo = StoreCouponUser::validAddressWhere()->where('id', $couponId)->where('uid', $uid)->find(); if (!$couponInfo) return self::setErrorInfo('选择的优惠劵无效!', true); $coupons = StoreCouponUser::getUsableCouponList($uid, ['valid' => $cartInfo], $payPrice); $flag = false; foreach ($coupons as $coupon) { if ($coupon['id'] == $couponId) { $flag = true; continue; } } if (!$flag) return self::setErrorInfo('不满足优惠劵的使用条件!', true); $payPrice = (float)bcsub($payPrice, $couponInfo['coupon_price'], 2); $res1 = StoreCouponUser::useCoupon($couponId); $couponPrice = $couponInfo['coupon_price']; } else { $couponId = 0; $couponPrice = 0; } if (!$res1) return self::setErrorInfo('使用优惠劵失败!', true); //$shipping_type = 1 快递发货 $shipping_type = 2 门店自提 $store_self_mention = sys_config('store_self_mention') ?? 0; if (!$store_self_mention) $shipping_type = 1; if ($shipping_type === 1) { //是否包邮 if ((isset($other['offlinePostage']) && $other['offlinePostage'] && $payType == 'offline')) $payPostage = 0; $payPrice = (float)bcadd($payPrice, $payPostage, 2); } else if ($shipping_type === 2) { //门店自提没有邮费支付 $priceGroup['storePostage'] = 0; $payPostage = 0; if (!$storeId && !$test) { return self::setErrorInfo('请选择门店', true); } } //积分抵扣 $res2 = true; $SurplusIntegral = 0; $useIntegral = false; if ($useIntegral && $userInfo['integral'] > 0) { $deductionPrice = (float)bcmul($userInfo['integral'], $other['integralRatio'], 2); if ($deductionPrice < $payPrice) { $payPrice = bcsub($payPrice, $deductionPrice, 2); $usedIntegral = $userInfo['integral']; $SurplusIntegral = 0; $res2 = false !== User::edit(['integral' => 0], $userInfo['uid'], 'uid'); } else { $deductionPrice = $payPrice; $usedIntegral = (float)bcdiv($payPrice, $other['integralRatio'], 2); $SurplusIntegral = bcsub($userInfo['integral'], $usedIntegral, 2); $res2 = false !== User::bcDec($userInfo['uid'], 'integral', $usedIntegral, 'uid'); $payPrice = 0; } $res2 = $res2 && false != UserBill::expend('积分抵扣', $uid, 'integral', 'deduction', $usedIntegral, $key, $userInfo['integral'], '购买商品使用' . floatval($usedIntegral) . '积分抵扣' . floatval($deductionPrice) . '元'); } else { $deductionPrice = 0; $usedIntegral = 0; } if (!$res2) return self::setErrorInfo('使用积分抵扣失败!', true); if ($payPrice <= 0) $payPrice = 0; if ($test) { self::rollbackTrans(); return [ 'total_price' => $priceGroup['totalPrice'], 'pay_price' => $payPrice, 'pay_postage' => $payPostage, 'coupon_price' => $couponPrice, 'deduction_price' => $deductionPrice, 'SurplusIntegral' => $SurplusIntegral, ]; } $orderInfo = [ 'uid' => $uid, 'order_id' => $test ? 0 : self::getNewOrderId(), 'real_name' => $addressInfo['real_name'], 'user_phone' => $addressInfo['phone'], 'user_address' => $addressInfo['province'] . ' ' . $addressInfo['city'] . ' ' . $addressInfo['district'] . ' ' . $addressInfo['detail'], 'cart_id' => $cartIds, 'total_num' => $totalNum, 'total_price' => $priceGroup['totalPrice'], 'total_postage' => $priceGroup['storePostage'], 'coupon_id' => $couponId, 'coupon_price' => $couponPrice, 'pay_price' => $payPrice, 'pay_postage' => $payPostage, 'deduction_price' => $deductionPrice, 'paid' => 0, 'pay_type' => $payType, 'use_integral' => $usedIntegral, 'gain_integral' => $gainIntegral, 'mark' => htmlspecialchars($mark), 'combination_id' => $combinationId, 'pink_id' => $pinkId, 'seckill_id' => $seckill_id, 'bargain_id' => $bargain_id, 'cost' => $priceGroup['costPrice'], 'is_channel' => $isChannel, 'add_time' => time(), 'unique' => $key, 'shipping_type' => $shipping_type, ]; if ($shipping_type === 2) { $orderInfo['verify_code'] = self::getStoreCode(); $orderInfo['store_id'] = SystemStore::getStoreDispose($storeId, 'id'); if (!$orderInfo['store_id']) return self::setErrorInfo('暂无门店无法选择门店自提!', true); } $order = self::create($orderInfo); if (!$order) return self::setErrorInfo('订单生成失败!', true); $res5 = true; foreach ($cartInfo as $cart) { //减库存加销量 if ($combinationId) $res5 = $res5 && StoreCombination::decCombinationStock($cart['cart_num'], $combinationId, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : ''); else if ($seckill_id) $res5 = $res5 && StoreSeckill::decSeckillStock($cart['cart_num'], $seckill_id, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : ''); else if ($bargain_id) $res5 = $res5 && StoreBargain::decBargainStock($cart['cart_num'], $bargain_id, isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : ''); else $res5 = $res5 && StoreProduct::decProductStock($cart['cart_num'], $cart['productInfo']['id'], isset($cart['productInfo']['attrInfo']) ? $cart['productInfo']['attrInfo']['unique'] : ''); } //保存购物车商品信息 $res4 = false !== StoreOrderCartInfo::setCartInfo($order['id'], $cartInfo); $res7 = $res8 = true; if($cartInfo[0]['productInfo']['id']) { $user_info = User::getUserInfo($uid); $insert_spell_data = [ 'uid' => $uid, 'nickname' => $user_info['nickname'], 'oid' => $order['id'], 'goods_id' => $cartInfo[0]['productInfo']['id'], 'status' => 0, 'is_auto' => $is_auto, 'is_pay' => 0, 'edit_time' => time(), 'add_time' => time(), ]; $res7 = StoreOrderSpell::insert($insert_spell_data); //如果系统没有记录,则新增一条 if( StoreOrderSpellUserLog::where('uid="'.$uid.'" AND goods_id="'.$cartInfo[0]['productInfo']['id'].'"')->count() == 0) { $insert_user_log = [ 'goods_id' => $cartInfo[0]['productInfo']['id'], 'uid' => $uid, ]; $res8 = StoreOrderSpellUserLog::insert($insert_user_log); } } //购物车状态修改 $res6 = false !== StoreCart::where('id', 'IN', $cartIds)->update(['is_pay' => 1]); if (!$res4 || !$res5 || !$res6 || !$res7 || !$res8) return self::setErrorInfo('订单生成失败!', true); //自动设置默认地址 UserRepository::storeProductOrderCreateEbApi($order, compact('cartInfo', 'addressId')); self::clearCacheOrderInfo($uid, $key); self::commitTrans(); StoreOrderStatus::status($order['id'], 'cache_key_create_order', '订单生成'); return $order; } catch (PDOException $e) { self::rollbackTrans(); return self::setErrorInfo('生成订单时SQL执行错误错误原因:' . $e->getMessage()); } catch (Exception $e) { self::rollbackTrans(); return self::setErrorInfo('生成订单时系统错误错误原因:' . $e->getMessage()); } } /** * 回退积分 * @param $order 订单信息 * @return bool */ public static function RegressionIntegral($order) { if ($order['paid'] || $order['status'] == -2 || $order['is_del']) return true; if ($order['use_integral'] <= 0) return true; if ((int)$order['status'] != -2 && (int)$order['refund_status'] != 2 && $order['back_integral'] >= $order['use_integral']) return true; $res = User::bcInc($order['uid'], 'integral', $order['use_integral']); if (!$res) return self::setErrorInfo('回退积分增加失败'); UserBill::income('积分回退', $order['uid'], 'integral', 'deduction', $order['use_integral'], $order['unique'], User::where('uid', $order['uid'])->value('integral'), '购买商品失败,回退积分' . floatval($order['use_integral'])); return false !== self::where('order_id', $order['order_id'])->update(['back_integral' => $order['use_integral']]); } /** * 回退库存和销量 * @param $order 订单信息 * @return bool * @throws hinkdbexceptionDataNotFoundException * @throws hinkdbexceptionModelNotFoundException * @throws hinkexceptionDbException */ public static function RegressionStock($order) { if ($order['status'] == -2 || $order['is_del']) return true; $combinationId = $order['combination_id']; $seckill_id = $order['seckill_id']; $bargain_id = $order['bargain_id']; $res5 = true; $cartInfo = StoreOrderCartInfo::where('cart_id', 'in', $order['cart_id'])->select(); foreach ($cartInfo as $cart) { //增库存减销量 if ($combinationId) $res5 = $res5 && StoreCombination::incCombinationStock($cart['cart_info']['cart_num'], $combinationId, isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique'] : ''); else if ($seckill_id) $res5 = $res5 && StoreSeckill::incSeckillStock($cart['cart_info']['cart_num'], $seckill_id, isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique'] : ''); else if ($bargain_id) $res5 = $res5 && StoreBargain::incBargainStock($cart['cart_info']['cart_num'], $bargain_id, isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique'] : ''); else $res5 = $res5 && StoreProduct::incProductStock($cart['cart_info']['cart_num'], $cart['cart_info']['productInfo']['id'], isset($cart['cart_info']['productInfo']['attrInfo']) ? $cart['cart_info']['productInfo']['attrInfo']['unique'] : ''); } return $res5; }