| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- <?php
- namespace addons\Agent\common\traits;
- use addons\Agent\common\enums\AgentEnum;
- use addons\Agent\common\enums\ComputingEnum;
- use addons\Agent\common\models\Agent;
- use addons\Agent\common\models\AgentDistributionSetting;
- use addons\Agent\common\models\AgentGoodsRepurchase;
- use common\enums\GoodsTypeEnum;
- use common\enums\StatusEnum;
- use common\helpers\FormatHelper;
- use common\models\mall\MallAddons;
- use common\models\order\Order;
- use common\models\order\OrderDetail;
- use common\models\user\UserPartitionRelationship;
- use services\common\UserWalletService;
- use yii\helpers\Json;
- trait DistributionRewardTrait
- {
- /**
- * @param array $order
- * @return bool
- */
- public function repurchaseReward(array $order)
- {
- // 执行奖励
- // 开关开启以后可以设置层级的分销奖励;每个商品可以设置奖励不同,层级可以自定义设置,一二级可以单独设置分佣,三级或者三级以上设置统一。
- // 例如:设置15层级,达到15层以后第16个人下单以后前面的15个人都可以拿奖励;假设第17个人下单下单了,找下单的前15代拿奖励,也就是2-16层级
- // 可以阶梯单独设置奖励
- try {
- $mall_id = $order['mall_id'];
- $order_id = $order['id'];
- $user_id = $order['user_id'];
- if (MallAddons::isInstall($mall_id, AgentEnum::ADDONS_NAME) == 0) return false;
- $setting = \Yii::$app->services->setting->addons->get($mall_id, AgentEnum::ADDONS_NAME, 'basic');
- if (empty($setting['is_enable'])) throw new \Exception('没开启渠道分红');
- $params['where'] = [['order_id' => $order_id], ['user_id' => $user_id], ['mall_id' => $mall_id]];
- $order_detail_list = OrderDetail::lists($params);
- if (empty($order_detail_list)) throw new \Exception('订单详情不存在');
- $parent_id_arr = UserPartitionRelationship::getParentIdArr($user_id);
- $parent_id_arr = array_reverse($parent_id_arr);
- $where = ['user_id' => $parent_id_arr, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED];
- $addons_agent_list = Agent::find()->where($where)->indexBy('user_id')->all();//查询经销商列表
- $agent_list = [];
- // 如果中间有非渠道长的那么就直接断掉后面的奖励
- foreach ($parent_id_arr as $parent_id) {
- if (empty($addons_agent_list[$parent_id])) break;
- $agent_list[] = $addons_agent_list[$parent_id];//按照关系排序
- }
- // 需要判断是否为复购 - 只有复购的情况下才会有
- // 非复购情况下那么就给上级
- $enable_repurchase_reward = (int) $setting['enable_repurchase_reward'];
- $agent = Agent::findOne(['user_id' => $user_id, 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]);// 查询购买者身份
- if ($enable_repurchase_reward) {
- $enable_repurchase_reward = Order::find()
- ->where(['mall_id' => $mall_id])
- ->andWhere(['user_id' => $user_id])
- ->andWhere(['<>', 'id', $order_id])
- ->andWhere(['pay_status' => StatusEnum::ENABLED])
- ->count();
- }
- // 如果本人是渠道长且有开启复购且当前订单是复购订单那么当前用户就拿第一代奖励
- // if ($enable_repurchase_reward == StatusEnum::ENABLED && !empty($agent)) {
- // array_unshift($agent_list, $agent);
- // }
- $wallet_insert = [];
- // 如果没有代理商,那么就不做分佣处理
- if (!empty($agent_list)) {
- $is_frozen = $setting['compute_type'] == ComputingEnum::ORDER_FINISH;
- foreach ($order_detail_list as $order_detail) {
- $distribution_settings = AgentDistributionSetting::find()
- ->where(['mall_id' => $mall_id])
- ->andWhere(['item_id' => $order_detail['goods_id']])
- ->andWhere(['status' => StatusEnum::ENABLED])
- ->select('value')
- ->column();
- // 判断配置了没
- if (empty($distribution_settings)) continue;
- if($order_detail['is_virtual'] == StatusEnum::ENABLED){
- //虚拟商品,支付后-直接订单完成,所以直接结算
- $is_frozen = false;
- }
- $tmp_agent_list = $agent_list;
- $tmp_enable_repurchase_reward = $enable_repurchase_reward;
- if (!empty($agent)) {
- // 独立设置
- if (AgentGoodsRepurchase::isAloneSetting($mall_id, $order_detail['goods_id'])) {
- // 判断当前用户是否买过, 如果当前用户没有买过当前商品那么就将自己剔除
- $tmp_enable_repurchase_reward =
- AgentGoodsRepurchase::isBuyCurrentGoods($mall_id, $user_id, $order_id, $order_detail['goods_id']) ?
- StatusEnum::ENABLED : StatusEnum::DISABLED;
- }
- if ($tmp_enable_repurchase_reward == StatusEnum::ENABLED) {
- array_unshift($tmp_agent_list, $agent); // 将自己排在第一位
- }
- }
- foreach ($distribution_settings as $distribution_setting) {
- $distribution_setting = Json::decode($distribution_setting);
- // 判断启用了没 - 如果有启用单独设置 那么也是可以执行的
- if (empty($distribution_setting['enable_repurchase_reward'])) continue;
- if (empty($distribution_setting['item_type']) || $distribution_setting['item_type'] != 'goods') continue;
- // 判断层级及分佣方式
- $rewards = $this->execReward($order_detail, $distribution_setting, $tmp_agent_list, $order['order_no'], $setting, $is_frozen);
- if (!empty($rewards)) {
- array_push($wallet_insert, ...$rewards);
- }
- }
- }
- if (!empty($wallet_insert)) {
- $res = UserWalletService::batchHandleByQueue($wallet_insert);
- if (empty($res)) {
- throw new \Exception(UserWalletService::getStaticError());
- }
- // 累加数据
- foreach ($wallet_insert as $user) {
- $agent = Agent::findOne(['user_id' => $user['user_id'], 'status'=>[StatusEnum::DISABLED, StatusEnum::ENABLED], 'mall_id' => $user['mall_id']]);
- if(empty($agent)) continue;
- $field = 'total_' . $user['wallet_type'];
- $agent->$field += $user['money'];
- if (!$agent->save()) throw new \Exception(Agent::getStaticError());
- }
- }
- }
- } catch (\Exception $e) {
- \Yii::error(FormatHelper::exception($e, __CLASS__ . "->" . __METHOD__));
- }
- return true;
- }
- /**
- * @param array $orderDetail
- * @param array $config
- * @param array $parentIds
- * @param string $order_no
- * @param array $setting
- * @param bool $is_frozen
- * @return array
- */
- protected function execReward(array $orderDetail, array $config, array $parentIds, string $order_no, array $setting, bool $is_frozen)
- {
- $insert_wallet = [];
- // 遍历所有上级
- foreach ($parentIds as $key => $agent) {
- // 控制在范围内
- if ($config['distribution_level_max'] < $key+1) break;
- $reward_amount = 0;
- // 需要判断是否独立设置 - 独立设置后 最终奖励那么就按独立设置的来处理
- switch ($key) {
- case 0:
- if ($config['distribution_level1'] > 0) {
- $reward_amount = $config['distribution_level1']; // 固定金额
- if ($config['distribution_type'] == 0) { // 百分比
- switch ($setting['computing_method']) {
- case 0: // 支付价格
- $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level1'] * 0.01);
- break;
- case 1: // 商品售价
- $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level1'] * 0.01);
- break;
- case 2: // 商品利润
- $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'],
- $orderDetail['num'], $config['distribution_level1'] * 0.01);
- break;
- }
- }
- }
- break;
- case 1:
- if ($config['distribution_level2'] > 0 && $config['distribution_level_max'] > 1) {
- $reward_amount = $config['distribution_level2']; // 固定金额
- if ($config['distribution_type'] == 0) { // 百分比
- switch ($setting['computing_method']) {
- case 0: // 支付价格
- $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level2'] * 0.01);
- break;
- case 1: // 商品售价
- $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level2'] * 0.01);
- break;
- case 2: // 商品利润
- $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'],
- $orderDetail['num'], $config['distribution_level2'] * 0.01);
- break;
- }
- }
- }
- break;
- default:
- // 必须保持在指定层级内
- if ($config['distribution_level3'] > 0 && $config['distribution_level_max'] > 2) {
- $reward_amount = $config['distribution_level3']; // 固定金额
- if ($config['distribution_type'] == 0) { // 百分比
- switch ($setting['computing_method']) {
- case 0: // 支付价格
- $reward_amount = $this->calcByPayAmount($orderDetail['goods_price'], $config['distribution_level3'] * 0.01);
- break;
- case 1: // 商品售价
- $reward_amount = $this->calcByGoodsSalePrice($orderDetail['price'], $orderDetail['num'], $config['distribution_level3'] * 0.01);
- break;
- case 2: // 商品利润
- $reward_amount = $this->calcByGoodsProfit($orderDetail['price'], $orderDetail['cost_price'],
- $orderDetail['num'], $config['distribution_level3'] * 0.01);
- break;
- }
- }
- }
- }
- if ($reward_amount > 0) {
- // ComputingEnum::AGENT_DISTRIBUTION_PREFIX . ($key + 1)
- $capital_type = ComputingEnum::AGENT_DISTRIBUTION_REWARD;
- $insert_wallet[] = $this->pack($agent->user_id, $orderDetail,
- $config['commission_type'], $reward_amount, $capital_type,
- $order_no, ComputingEnum::AGENT_DISTRIBUTION_REWARD_TXT, $is_frozen);
- }
- }
- return $insert_wallet;
- }
- /**
- * @param int $user_id
- * @param array $orderDetail
- * @param string $commission_type
- * @param string $amount
- * @param string $capital_type
- * @param string $order_no
- * @param string $reward_type
- * @param bool $is_frozen
- * @return array
- */
- protected function pack(int $user_id, array $orderDetail, string $commission_type, string $amount,
- string $capital_type, string $order_no, string $reward_type, bool $is_frozen)
- {
- // 获取奖励名称
- $commission_name = \Yii::$app->services->setting->mall->get($orderDetail['mall_id'], "{$commission_type}.{$commission_type}_name");
- if (empty($commission_name)) {
- switch ($commission_type) {
- case UserWalletService::WALLET_TYPE_COMMISSION:
- $commission_name = '佣金';
- break;
- default:
- $commission_name = '';
- }
- }
- $desc = "用户($user_id),获得订单({$orderDetail['order_id']})奖励,奖励类型: $reward_type, 奖励: $amount $commission_name";
- return [
- 'mall_id' => $orderDetail['mall_id'],
- 'user_id' => $user_id,
- 'is_frozen' => $is_frozen,
- 'wallet_type' => $commission_type,
- 'money' => $amount,
- 'desc' => $desc,
- 'source_table' => 'order_detail',
- 'source_table_id' => $orderDetail['id'], // 取出订单ID?
- 'from_type' => AgentEnum::ADDONS_NAME,
- 'capital_type' => $capital_type,
- 'order_no' => $order_no, // 这里需要订单号
- 'contributor_name' => $orderDetail['goods_name'],
- 'contributor_id' => $orderDetail['user_id'],
- 'contributor_money' => $orderDetail['goods_price'],
- ];
- }
- /**
- * @param $goods_price
- * @param $cardinality
- * @return string
- */
- protected function calcByPayAmount($goods_price, $cardinality)
- {
- return bcmul($goods_price, $cardinality, 2);
- }
- /**
- * @param $goods_price
- * @param $num
- * @param $cardinality
- * @return string
- */
- protected function calcByGoodsSalePrice($goods_price, $num, $cardinality)
- {
- return bcmul(bcmul($goods_price, $num, 2), $cardinality, 2);
- }
- /**
- * @param $goods_price
- * @param $goods_const_price
- * @param $num
- * @param $cardinality
- * @return string
- */
- protected function calcByGoodsProfit($goods_price, $goods_const_price, $num, $cardinality)
- {
- return bcmul(bcmul(bcsub($goods_price, $goods_const_price, 2), $num, 2),
- $cardinality, 2);
- }
- protected function traitUnshiftAgentList(int $enable_repurchase_reward, array $agent_list, array $orders, Agent $agent)
- {
- }
- }
|