| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- <?php
- namespace addons\WechatVideoShop\common\logic;
- use addons\WechatVideoShop\common\enums\WechatVideoShopEnums;
- use addons\WechatVideoShop\common\models\WechatVideoShopCommission;
- use addons\WechatVideoShop\common\models\WechatVideoShopGoodsSetting;
- use addons\WechatVideoShop\common\models\WechatVideoShopLevel;
- use addons\WechatVideoShop\common\models\WechatVideoShopOrder;
- use addons\WechatVideoShop\common\models\WechatVideoShopSharer;
- use common\enums\OrderStatusEnum;
- use common\enums\StatusEnum;
- use common\helpers\FormatHelper;
- use common\models\common\CapitalLog;
- use common\models\order\OrderDetail;
- use services\common\UserWalletService;
- use yii\helpers\Json;
- class RewardLogic
- {
- /**
- * 支付事件执行
- * @param array $order
- * @param array $config
- * @return bool
- */
- public static function reward(array $order, array $config)
- {
- try {
- $goods_ids = array_column($order['detail'], "goods_id");
- if (empty($goods_ids)) return true;
- $setting = WechatVideoShopGoodsSetting::lists([
- 'where' => [
- ['mall_id' => $order['mall_id']],
- ['status' => StatusEnum::ENABLED],
- // ['is_enable' => StatusEnum::ENABLED], // 必须是启用状态
- ['item_id' => $goods_ids]
- ],
- 'select'=> ['item_id', 'config', 'is_enable'],
- 'index' => 'item_id'
- ]);
- $wallet_insert = [];
- $commission_insert = [];
- $is_frozen = $config['settlement_type'] == OrderStatusEnum::ACCOMPLISH ? StatusEnum::ENABLED : StatusEnum::DISABLED;
- $score_name = \Yii::$app->services->setting->mall->get($order['mall_id'], "score.score_name");
- $score_name = !empty($score_name) ? $score_name : '积分';
- $wechat_video_shop_order = WechatVideoShopOrder::getOne([
- ['order_id' => $order['id']]
- ]);
- if (empty($wechat_video_shop_order->parent_id)) {
- // 没有上级可以进行分佣
- return true;
- }
- $sharer = $wechat_video_shop_order->sharer;
- if (empty($sharer)) {
- // 没有上级可以进行分佣
- return true;
- }
- // 当前用户等级
- $level = $sharer->level;
- $reward_user_id = $wechat_video_shop_order->parent_id;
- if (!empty($level)) { // 等级配置奖励
- $level_setting = WechatVideoShopLevel::getOne([
- ['level' => $level],
- ['mall_id' => $order['mall_id']],
- ['status' => StatusEnum::ENABLED]
- ]);
- }
- foreach ($order['detail'] as $item) {
- // 判断有没有启用
- $tmp_config = [
- "compute_type" => $config['compute_type'],
- "reward_commission_type" => $config['reward_commission_type'],
- "reward_commission" => $config['reward_commission'],
- "reward_score_type" => $config['reward_score_type'],
- "reward_score" => $config['reward_score'],
- ];
- if (!empty($level_setting)) { // 等级配置
- $tmp_config['reward_commission_type'] = $level_setting['reward_commission_type'];
- $tmp_config['reward_commission'] = $level_setting['reward_commission'];
- $tmp_config['reward_score_type'] = $level_setting['reward_score_type'];
- $tmp_config['reward_score'] = $level_setting['reward_score'];
- }
- if (!empty($setting[$item['goods_id']])) { // 独立设置 - 必须有等级,不然无法获取奖励金额 - 默认等级为0
- if (empty($setting[$item['goods_id']]['is_enable'])) continue; // 分佣没有启用
- // 遍历所有奖励,判断是否为独立设置
- $tmp_setting = Json::decode($setting[$item['goods_id']]['config']);
- if (!empty($tmp_setting['commission']['is_independent_setting'])) { // 独立设置
- $tmp_config['reward_commission_type'] = $tmp_setting['commission']['reward_type'] ?? $config['reward_commission_type'];
- $tmp_config['reward_commission'] = $tmp_setting['commission']['level'][$level] ?? $config['reward_commission'];
- }
- if (!empty($tmp_setting['score']['is_independent_setting'])) { // 独立设置
- $tmp_config['reward_score_type'] = $tmp_setting['score']['reward_type'] ?? $config['reward_score_type'];
- $tmp_config['reward_score'] = $tmp_setting['score']['level'][$level] ?? $config['reward_score'];
- }
- }
- if ($tmp_config['reward_commission'] > 0) {
- [$commission, $remark] = self::getCommission($tmp_config, $config, $item, UserWalletService::WALLET_TYPE_COMMISSION, "佣金");
- $wallet_insert[] = self::packWalletInsert($reward_user_id, $order, $item, $is_frozen,
- UserWalletService::WALLET_TYPE_COMMISSION, $commission,
- "分销员 [$reward_user_id] 推荐用户 [{$order['user_id']}] 从微信视频号小店下单 [{$order['order_no']}] 获得 $commission 佣金奖励",
- WechatVideoShopEnums::ADDONS_NAME, WechatVideoShopEnums::ADDONS_NAME);
- $commission_insert[] = self::packCommissionInsert($reward_user_id, $order, $item,
- WechatVideoShopEnums::REWARD_TYPE_COMMISSION, $commission, $is_frozen, $remark, $wechat_video_shop_order->shop_id);
- if (empty($is_frozen)) $sharer->total_commission += $commission;
- }
- if ($tmp_config['reward_score'] > 0) {
- [$commission, $remark] = self::getCommission($tmp_config, $config, $item, UserWalletService::WALLET_TYPE_SCORE, $score_name);
- $wallet_insert[] = self::packWalletInsert($reward_user_id, $order, $item, $is_frozen,
- UserWalletService::WALLET_TYPE_SCORE, $commission,
- "分销员 [$reward_user_id] 推荐用户 [{$order['user_id']}] 从微信视频号小店下单 [{$order['order_no']}] 获得 $commission $score_name 奖励",
- WechatVideoShopEnums::ADDONS_NAME, WechatVideoShopEnums::ADDONS_NAME);
- if (empty($is_frozen)) $sharer->total_score += $commission;
- $commission_insert[] = self::packCommissionInsert($reward_user_id, $order, $item,
- WechatVideoShopEnums::REWARD_TYPE_SCORE, $commission, $is_frozen, $remark, $wechat_video_shop_order->shop_id);
- }
- }
-
- $t = \Yii::$app->db->beginTransaction();
- if (!empty($commission_insert)) {
- // 写入插件记录
- WechatVideoShopCommission::find()->createCommand()
- ->batchInsert(WechatVideoShopCommission::tableName(),
- array_keys($commission_insert[0]), $commission_insert)->execute();
- // 给当前用户累加数据
- $sharer->total_order += 1; // 累加订单数量
- // 非冻结的才需要累加
- $sharer->total_sales += $order['pay_money']; // 累加销售金额
- $sharer->total_customers = WechatVideoShopOrder::find()
- ->where(['parent_id' => $sharer->user_id])
- ->andWhere(['is_pay' => StatusEnum::ENABLED])
- ->groupBy('user_id')->count();
- if (!$sharer->save()) throw new \Exception($sharer->getErrorMessage());
- }
- if (!empty($wallet_insert)) {
- UserWalletService::batchHandleByQueue($wallet_insert);
- if (!empty(UserWalletService::getStaticError())) throw new \Exception(UserWalletService::getStaticError());
- }
- $t->commit();
- } catch (\Exception $e) {
- if (!empty($t)) $t->rollBack();
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- var_dump($e->getMessage(), $e->getLine(), $e->getFile());
- return false;
- }
- return true;
- }
- /**
- * @param int $user_id
- * @param array $order
- * @param array $goods
- * @param bool $is_frozen
- * @param string $wallet_type
- * @param $commission
- * @param string $desc
- * @param string $from_type
- * @param string $capital_type
- * @return array
- */
- protected static function packWalletInsert(int $user_id, array $order, array $goods, bool $is_frozen,
- string $wallet_type, $commission, string $desc, string $from_type,
- string $capital_type)
- {
- return [
- 'mall_id' => $order['mall_id'],
- 'user_id' => $user_id,
- 'is_frozen' => $is_frozen,
- 'wallet_type' => $wallet_type,
- 'money' => $commission,
- 'desc' => $desc,
- 'source_table' => 'order_detail',
- 'source_table_id' => $goods['id'],
- 'from_type' => $from_type,
- 'capital_type' => $capital_type,
- 'order_no' =>$order['order_no'],
- 'contributor_name' =>$goods['goods_name'],
- 'contributor_id' => $order['user_id'],
- 'contributor_money' =>$goods['goods_price'],
- ];
- }
- /**
- * @param int $user_id
- * @param array $order
- * @param array $goods
- * @param string $commission_type
- * @param $commission
- * @param int $settle_status
- * @param string $remark
- * @param int $shop_id
- * @return array
- */
- protected static function packCommissionInsert(int $user_id, array $order, array $goods,
- string $commission_type, $commission, int $settle_status,string $remark, int $shop_id)
- {
- return [
- 'mall_id' => $order['mall_id'],
- 'user_id' => $user_id,
- 'buy_user_id' => $order['user_id'],
- 'order_id' => $order['id'],
- 'order_no' => $order['order_no'],
- 'order_amount' => $order['pay_money'],
- 'remark' => $remark,
- 'settle_status' => $settle_status == StatusEnum::DISABLED ? WechatVideoShopEnums::SETTLE_STATUS_COMPLETE : WechatVideoShopEnums::SETTLE_STATUS_FREEZE,
- 'commission' => bcmul($commission, 100),
- 'commission_type' => $commission_type,
- 'goods_id' => $goods['id'],
- 'created_at' => time(),
- 'updated_at' => time(),
- 'shop_id' => $shop_id
- ];
- }
- /**
- * @param array $setting
- * @param array $config
- * @param array $goods
- * @param string $commission_type
- * @param string $commission_name
- * @return array
- */
- protected static function getCommission(array $setting, array $config, array $goods, string $commission_type, string $commission_name)
- {
- $commission = bcmul($setting["reward_{$commission_type}"], $goods['num'], 2);
- $remark = "固定";
- if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) {
- $remark = "比例";
- }
- // 百分比
- $suffix = "";
- switch ($config['compute_type']) {
- case 0: // 实际支付金额
- if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) {
- $commission = bcmul(bcmul($setting["reward_$commission_type"], $goods['goods_price'], 2), 0.01, 2);
- }
- $suffix = "(按实际支付金额计算)";
- break;
- case 1: // 商品售价
- if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) {
- $commission = bcmul(bcmul($setting["reward_$commission_type"], bcmul($goods['price'], $goods['num'], 2), 2), 0.01, 2);
- }
- $suffix = "(按商品售价计算)";
- break;
- case 2: // 商品利润
- if ($setting["reward_{$commission_type}_type"] == StatusEnum::ENABLED) {
- $commission = bcmul(bcmul($setting["reward_$commission_type"], bcmul(bcsub($goods['price'], $goods['cost_price'], 2),
- $goods['num'], 2), 2), 0.01, 2);
- }
- $suffix = "(按商品利润计算)";
- break;
- }
- $remark .= "{$commission_name}[{$setting["reward_$commission_type"]}] $suffix";
- return [$commission, $remark];
- }
-
- /**
- * 完成事件执行
- * @param array $order
- * @param array $config
- * @return bool
- */
- public static function unfreeze(array $order, array $config)
- {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $order_detail_list = $order['detail'] ?? [];
- if (empty($order_detail_list)) return true;
- $source_table_id_arr = array_column($order_detail_list, 'id');
- $capital_types = [
- WechatVideoShopEnums::ADDONS_NAME
- ];
- $where = [
- ['source_table' => 'order_detail'],
- ['source_table_id' => $source_table_id_arr],
- ['from_type' => WechatVideoShopEnums::ADDONS_NAME],
- ['capital_type' => $capital_types],
- ['status' => CapitalLog::STATUS_WAIT_SEND]
- ];
- $params['where'] = $where;
- //佣金
- $wallet_type = 'commission';
- CapitalLog::$capitalType = "{$wallet_type}_frozen";
- $commission_list = CapitalLog::lists($params);
- // 取出分享员
- if ($commission_list) {
- $sharer_user_id = $commission_list[0]['user_id'] ?? 0;
- $sharer = self::getSharer($sharer_user_id);
- foreach ($commission_list as $item) {
- $res = UserWalletService::unfrozen($item['id'], $wallet_type);
- if (!empty($sharer) && $res) {
- if ($item['change_type'] == 'add') $sharer->total_commission += $item['change_num'];
- } else {
- \Yii::error(__METHOD__ . " 分享员不存在 -> {$order['id']} -> {$sharer_user_id} -> {$res}");
- }
- }
- }
- //积分
- $wallet_type = 'score';
- CapitalLog::$capitalType = "{$wallet_type}_frozen";
- $score_list = CapitalLog::lists($params);
- if ($score_list) {
- if (empty($sharer)) {
- $sharer_user_id = $score_list[0]['user_id'] ?? 0;
- $sharer = self::getSharer($sharer_user_id);
- }
- foreach ($score_list as $item) {
- $res = UserWalletService::unfrozen($item['id'], $wallet_type);
- // change_num
- if (!empty($sharer) && $res) {
- if ($item['change_type'] == 'add') $sharer->total_commission += $item['change_num'];
- } else {
- \Yii::error(__METHOD__ . " 分享员不存在 -> {$order['id']} -> {$sharer_user_id} -> {$res}");
- }
- }
- }
- WechatVideoShopCommission::updateAll(['settle_status' => WechatVideoShopEnums::SETTLE_STATUS_COMPLETE], ['order_id' => $order['id']]);
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- var_dump($e->getMessage());
- return false;
- }
- return true;
- }
- /**
- * 退款完成事件执行
- * @param array $refund
- * @param array $config
- * @return bool
- */
- public static function refund(array $refund, array $config)
- {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $order_detail_id = $refund['order_detail_id'];
- $capital_types = [
- WechatVideoShopEnums::ADDONS_NAME
- ];
- $where = [
- ['source_table' => 'order_detail'],
- ['source_table_id' => $order_detail_id],
- ['from_type' => WechatVideoShopEnums::ADDONS_NAME],
- ['capital_type' => $capital_types],
- ['status' => CapitalLog::STATUS_WAIT_SEND]
- ];
- $params['where'] = $where;
- //佣金
- $wallet_type = 'commission';
- CapitalLog::$capitalType = "{$wallet_type}_frozen";
- $commission_list = CapitalLog::lists($params);
- if (!empty($commission_list)) { // 默认会删除?
- // 执行删除
- }
- $wallet_type = 'score';
- CapitalLog::$capitalType = "{$wallet_type}_frozen";
- $score_list = CapitalLog::lists($params);
- if (!empty($score_list)) {
- }
- $t->commit();
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error(FormatHelper::exception($e, __METHOD__));
- return false;
- }
- return true;
- }
- /**
- * @param int $user_id
- * @return WechatVideoShopSharer|null
- */
- protected static function getSharer(int $user_id)
- {
- return WechatVideoShopSharer::getOne([
- ['user_id' => $user_id],
- ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]],
- ]);
- }
- }
|