| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- <?php
- namespace common\services\mall;
- use common\enums\EventNameEnum;
- use common\enums\PayTypeEnum;
- use common\enums\RefundStatusEnum;
- use common\enums\RefundTypeEnum;
- use common\models\order\Order;
- use common\models\order\OrderAchievementGoods;
- use common\models\order\OrderRefund;
- use common\models\statistics\UserAchievementStatistics;
- use common\models\statistics\UserAchievementStatisticsTotal;
- use common\models\statistics\UserTeamAchievementStatistics;
- use common\models\statistics\UserTeamDateAchievementStatistics;
- use Yii;
- /**
- * 业绩service
- *
- * @property-read null|array|mixed $achievementConfig
- */
- class AchievementService extends BaseService
- {
- /**
- * 获取业绩相关配置
- *
- * @return array|mixed|null
- */
- public function getAchievementConfig()
- {
- return Yii::$app->services->setting->mall->get($this->mall_id, 'order');
- }
- /**
- * 返回业绩商品是不是全部都退了
- *
- * @param int $orderId
- * @param bool $isRefund
- *
- * @return bool
- */
- public function achievementGoodsIsAllRefund(int $orderId, bool $isRefund = false): bool
- {
- $order = Order::getOne(
- [
- ['id' => $orderId]
- ],
- true,
- [
- 'detail' => function ($query) {
- $query->select('id, order_id, goods_id');
- }
- ],
- false,
- 'id'
- );
- $detailsIds = array_column($this->getAchievementOrderDetail($order['detail'], $isRefund), 'id');
- // 找订单退款表
- $exchangeOrderIds = OrderRefund::find()
- ->where(['order_detail_id' => $detailsIds, 'refund_status' => RefundStatusEnum::FINISH, 'type' => [RefundTypeEnum::MONEY, RefundTypeEnum::MONEY_AND_PRODUCT]])
- ->count();
- if (!$exchangeOrderIds) {
- return false;
- }
- return count($detailsIds) == $exchangeOrderIds;
- }
- /**
- * 根据订单详情返回满足业绩配置的订单详情
- *
- * @param array $orderDetails
- * @param bool $isRefund
- *
- * @return array
- */
- public function getAchievementOrderDetail(array $orderDetails, bool $isRefund = false): array
- {
- // 如果是退款直接查询当时有没有加过业绩,不管当前的配置是怎么样
- if ($isRefund) {
- $orderId = $orderDetails[0]['order_id'] ?? 0;
- $achievementGoodsIds = json_decode(
- OrderAchievementGoods::find()
- ->where(['order_id' => $orderId])
- ->select('goods_ids')
- ->scalar(),
- true
- );
- } else {
- $config = $this->getAchievementConfig();
- if (empty($config['is_designated_achievement_goods'])) {
- return $orderDetails;
- }
- $achievementGoodsIds = json_decode($config['achievement_goods_ids'], true);
- }
- if (empty($achievementGoodsIds)) {
- return [];
- }
- $resOrderDetails = [];
- foreach ($orderDetails as $detail) {
- if (in_array($detail['goods_id'], $achievementGoodsIds)) {
- $resOrderDetails[] = $detail;
- }
- }
- return $resOrderDetails;
- }
- /**
- * 根据事件类型返回用户和团队统计所需保存的数据
- *
- * @param string $type
- * @param array $order 订单创建时传的是多个订单,二维数组
- *
- * @return array
- */
- public function getStatisticsDataByType(string $type, array $order): array
- {
- $resData = [
- 'user' => [],
- 'team' => [
- 'direct' => [],
- 'indirect' => [],
- 'team' => [],
- ]
- ];
- $isRefund = $type === EventNameEnum::ORDER_REFUND;
- $resOrderDetails = $this->getAchievementOrderDetail($order['detail'], $isRefund);
- if (empty($resOrderDetails)) {
- return $resData;
- }
- $orderAchievement = array_sum(array_column($resOrderDetails, 'goods_price'));
- $orderOriginalGoodsPrice = array_sum(array_column($resOrderDetails, 'original_goods_price'));
- switch ($type) {
- // 维护创建订单支付和订单退款时所需维护的字段
- case EventNameEnum::ORDER_PAY:
- case EventNameEnum::ORDER_REFUND:
- // 已支付时,维护订单的业绩商品id
- if (EventNameEnum::ORDER_PAY === $type) {
- OrderAchievementGoods::setData([
- 'mall_id' => $this->mall_id,
- 'user_id' => $order['user_id'],
- 'order_id' => $order['id'],
- 'order_details_ids' => array_column($resOrderDetails, 'id'),
- 'goods_ids' => array_column($resOrderDetails, 'goods_id')
- ]);
- }
- $resData['user'] = [
- 'user_goods_price_total' => $orderAchievement,
- 'pay_goods_num' => array_sum(array_column($resOrderDetails, 'num')),
- 'pay_selling_price' => $orderOriginalGoodsPrice,
- 'balance_pay' => $order['payment_type'] === PayTypeEnum::BALANCE ? $orderAchievement : 0,
- 'wechat_pay' => $order['payment_type'] === PayTypeEnum::WECHAT ? $orderAchievement : 0,
- 'ali_pay' => $order['payment_type'] === PayTypeEnum::ALI ? $orderAchievement : 0,
- ];
- $resData['team']['direct'] = [
- 'user_direct_order_price_total' => $orderAchievement,
- 'user_direct_pay_selling_price' => $orderOriginalGoodsPrice,
- ];
- $resData['team']['indirect'] = [
- 'user_indirect_order_price_total' => $orderAchievement,
- 'user_indirect_pay_selling_price' => $orderOriginalGoodsPrice,
- ];
- $resData['team']['team'] = [
- 'team_pay_selling_price' => $orderOriginalGoodsPrice,
- 'team_goods_price_total' => $orderAchievement,
- ];
- // 已支付和或者退款并且全退了的订单才减少数量
- if (
- $type === EventNameEnum::ORDER_PAY ||
- $this->achievementGoodsIsAllRefund($order['id'], $isRefund)
- ) {
- $resData['user']['user_order_num'] = 1;
- $resData['team']['direct']['user_direct_order_total'] = 1;
- $resData['team']['indirect']['user_indirect_order_total'] = 1;
- $resData['team']['team']['team_order_num'] = 1;
- }
- // 退款就负数
- if ($type === EventNameEnum::ORDER_REFUND) {
- $this->convertValuesToNegative($resData);
- }
- break;
- // 维护创建订单完成所需维护的字段
- case EventNameEnum::ORDER_FINISH:
- $resData['user'] = [
- 'finish_order_num' => 1,
- 'finish_order_money' => $orderAchievement,
- 'finish_goods_num' => array_sum(array_column($resOrderDetails, 'num')),
- 'finish_selling_price' => $orderOriginalGoodsPrice,
- ];
- $resData['team']['direct'] = [
- 'user_direct_finish_selling_price' => $orderOriginalGoodsPrice
- ];
- $resData['team']['indirect'] = [
- 'user_indirect_finish_selling_price' => $orderOriginalGoodsPrice,
- ];
- $resData['team']['team'] = [
- 'team_finish_order_total' => 1,
- 'team_finish_order_price_total' => $orderAchievement,
- 'team_finish_selling_price' => $orderOriginalGoodsPrice,
- ];
- break;
- }
- return $resData;
- }
- /**
- * 数字转为负数
- *
- * @param $array
- *
- * @return void
- */
- public function convertValuesToNegative(&$array) {
- foreach ($array as &$value) {
- if (is_array($value)) {
- $this->convertValuesToNegative($value);
- } elseif (is_numeric($value)) {
- $value = -abs($value);
- }
- }
- }
- /**
- * 保存业绩统计数据
- *
- * @param string $eventName
- * @param array $baseData 包含:日期 用户id
- * @param array $order
- * @param bool $isIncr
- *
- * @return void
- */
- public function saveAchievementStatisticsData(
- string $eventName,
- array $baseData,
- array $order,
- bool $isIncr = true
- )
- {
- $statisticsData = $this->getStatisticsDataByType($eventName, $order);
- $baseData['mall_id'] = $this->mall_id;
- if (!empty($statisticsData['user'])) {
- UserAchievementStatistics::saveUserStatisticsData($baseData, $statisticsData['user'], $isIncr);
- UserAchievementStatisticsTotal::saveUserStatisticsData($baseData, $statisticsData['user'], $isIncr);
- }
- if (!empty($statisticsData['team']['team']) || !empty($statisticsData['team']['direct']) || !empty($statisticsData['team']['indirect'])) {
- UserTeamAchievementStatistics::saveStatisticsTotal(
- $baseData,
- $statisticsData['team']['team'],
- $isIncr,
- $statisticsData['team']['direct'],
- $statisticsData['team']['indirect']
- );
- UserTeamDateAchievementStatistics::saveStatistics(
- $baseData,
- $statisticsData['team']['team'],
- $isIncr,
- $statisticsData['team']['direct'],
- $statisticsData['team']['indirect']
- );
- }
- }
- }
|