| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- <?php
- namespace common\models\statistics;
- use common\helpers\FormatHelper;
- use common\models\base\BaseActiveRecord;
- use common\models\user\UserPartitionRelationship;
- use Exception;
- use Yii;
- use yii\db\ActiveQuery;
- /**
- * 团队统计数据
- */
- abstract class BaseUserTeamStatistics extends BaseActiveRecord
- {
- /**
- * 是否是根据日期统计
- *
- * @var bool
- */
- const IS_BY_DATE = true;
- /**
- * 允许自增的字段
- *
- * @var string[]
- */
- const ALLOW_INCR_FIELD = [
- 'user_direct_order_total',
- 'user_indirect_order_total',
- 'user_direct_order_price_total',
- 'user_indirect_order_price_total',
- 'team_finish_order_total',
- 'team_finish_order_price_total',
- 'user_direct_pay_selling_price',
- 'user_direct_finish_selling_price',
- 'user_indirect_pay_selling_price',
- 'user_indirect_finish_selling_price',
- 'team_finish_selling_price',
- 'team_pay_selling_price',
- 'team_goods_price_total',
- 'team_order_num',
- ];
- /**
- * 允许自减的字段
- *
- * @var string[]
- */
- const ALLOW_DECR_FIELD = [
- 'user_direct_order_total',
- 'user_indirect_order_total',
- 'user_direct_order_price_total',
- 'user_indirect_order_price_total',
- 'user_direct_pay_selling_price',
- 'user_indirect_pay_selling_price',
- 'team_pay_selling_price',
- 'team_goods_price_total',
- 'team_order_num',
- ];
- /**
- * 分了几张表
- */
- const TABLE_NUM = 10;
- /**
- * 当前表
- *
- * @var integer $currentTableNum
- */
- protected static $currentTableNum;
- /**
- * 切割规则
- *
- * @param integer $user_id
- *
- * @return int
- */
- public static function sliceRule(int $user_id): int
- {
- return $user_id % 10 ?: 10;
- }
- /**
- * @param int $tableNum
- * @param bool $isSliceRule
- *
- * @return ActiveQuery
- */
- public static function setTableNumAndReturnSelf(int $tableNum, bool $isSliceRule = true)
- {
- static::$currentTableNum = $isSliceRule ? $tableNum : self::sliceRule($tableNum);
- return static::find();
- }
- /**
- * 保存统计数据(整个上级都需要加)(只支持分表之后的表)
- *
- * @param array $baseData 基础数据(不需要保存的数据)
- * @param array $teamData 团队需要保存的数据
- * @param bool $isIncr 是否是自增
- * @param array $directData 直推需要保存的数据
- * @param array $indirectData 间推需要保存的数据
- *
- * @return bool
- */
- public static function saveStatistics(
- array $baseData,
- array $teamData,
- bool $isIncr = true,
- array $directData = [],
- array $indirectData = []
- ): bool
- {
- // 找出整个群组的人
- $parentUserIds = $baseData['parents_user_ids'] ?? UserPartitionRelationship::getParentIdArr($baseData['user_id']);
- if (empty($parentUserIds)) {
- return true;
- }
- // 直推ID
- $parentId = end($parentUserIds);
- // 间推ID
- $secondParentId = prev($parentUserIds);
- if (static::IS_BY_DATE) {
- $baseDateWhere = ['date' => $baseData['date']];
- } else {
- $baseDateWhere = [];
- }
- // 切割规则
- $sliceRuleUserIds = [];
- foreach ($parentUserIds as $userId) {
- $sliceRuleUserIds[static::sliceRule($userId)][] = $userId;
- }
- // 检查上级不存在的数据
- $findParentUserIds = [];
- foreach ($sliceRuleUserIds as $tableNum => $sliceRuleUserIdsItem) {
- $baseDateWhere['user_id'] = $sliceRuleUserIdsItem;
- $userIdsColumn = static::setTableNumAndReturnSelf($tableNum)
- ->where($baseDateWhere)
- ->select('user_id')
- ->column() ?: [];
- $findParentUserIds[] = $userIdsColumn;
- }
- $findParentUserIds = array_merge(...$findParentUserIds);
- $now = time();
- // 找差集
- $noExistUserIds = array_diff($parentUserIds, $findParentUserIds);
- if ($noExistUserIds) {
- $batchInsertData = [];
- $batchInsertField = ['mall_id', 'user_id', 'created_at', 'updated_at'];
- if (static::IS_BY_DATE) {
- $batchInsertField[] = 'date';
- }
- foreach ($noExistUserIds as $key => $noExistUserId) {
- $batchInsertData[self::sliceRule($noExistUserId)][$key] = [
- 'mall_id' => $baseData['mall_id'],
- 'user_id' => $noExistUserId,
- 'created_at' => $now,
- 'updated_at' => $now,
- ];
- if (static::IS_BY_DATE) {
- $batchInsertData[self::sliceRule($noExistUserId)][$key]['date'] = $baseData['date'];
- }
- }
- try {
- foreach ($batchInsertData as $tableNum => $values) {
- static::$currentTableNum = $tableNum;
- Yii::$app->db->createCommand()->batchInsert(
- static::tableName(),
- $batchInsertField,
- array_values($values)
- )->execute();
- }
- } catch (Exception $e) {
- $desc = sprintf(
- '团队统计,插入基础统计数据失败,data: %s',
- json_encode([
- 'class' => static::class,
- 'agrs' => func_get_args(),
- 'saveData' => array_merge(['tableName' => static::tableName()], compact('batchInsertField', 'batchInsertData'))
- ])
- );
- Yii::error(FormatHelper::exception($e, $desc));
- }
- }
- [
- 'allowSaveTeamData' => $allowSaveTeamData,
- 'allowSaveDirectData' => $allowSaveDirectData,
- 'allowSaveIndirectData' => $allowSaveIndirectData
- ] = self::getAllowSaveData($isIncr, $teamData, $directData, $indirectData);
- try {
- // 群组总业绩、群组产品总额、群组订单总数。(不包含自己)
- if ($allowSaveTeamData) {
- foreach ($sliceRuleUserIds as $tableNum => $sliceRuleUserIdsItem) {
- $baseDateWhere['user_id'] = $sliceRuleUserIdsItem;
- static::$currentTableNum = $tableNum;
- static::updateAllCounters($allowSaveTeamData, $baseDateWhere);
- }
- }
-
- // 保存直推数据
- if ($parentId && $allowSaveDirectData) {
- $baseDateWhere['user_id'] = $parentId;
- static::$currentTableNum = self::sliceRule($parentId);
- static::updateAllCounters($allowSaveDirectData, $baseDateWhere);
- }
- // 保存间推数据
- if ($secondParentId && $allowSaveIndirectData) {
- $baseDateWhere['user_id'] = $secondParentId;
- static::$currentTableNum = self::sliceRule($secondParentId);
- static::updateAllCounters($allowSaveIndirectData, $baseDateWhere);
- }
- } catch (Exception $e) {
- $desc = sprintf(
- '保存团队统计数据失败,data: %s',
- json_encode([
- 'class' => static::class,
- 'agrs' => func_get_args(),
- 'saveData' => compact('allowSaveTeamData', 'allowSaveDirectData', 'allowSaveIndirectData')
- ])
- );
- Yii::error(FormatHelper::exception($e, $desc));
- return false;
- }
- return true;
- }
- /**
- * 保存统计数据(整个上级都需要加)(只支持分表之后的表)
- *
- * @param array $baseData 基础数据(不需要保存的数据)
- * @param array $teamData 团队需要保存的数据
- * @param bool $isIncr 是否是自增
- * @param array $directData 直推需要保存的数据
- * @param array $indirectData 间推需要保存的数据
- *
- * @return bool
- */
- public static function saveStatisticsTotal(
- array $baseData,
- array $teamData,
- bool $isIncr = true,
- array $directData = [],
- array $indirectData = []
- ): bool
- {
- // 找出整个群组的人
- $parentUserIds = $baseData['parents_user_ids'] ?? UserPartitionRelationship::getParentIdArr($baseData['user_id']);
- if (empty($parentUserIds)) {
- return true;
- }
- // 直推ID
- $parentId = end($parentUserIds);
- // 间推ID
- $secondParentId = prev($parentUserIds);
-
- if (static::IS_BY_DATE) {
- $baseDateWhere = ['date' => $baseData['date']];
- } else {
- $baseDateWhere = [];
- }
- // 检查上级不存在的数据
- $baseDateWhere['user_id'] = $parentUserIds;
- $findParentUserIds = static::find()
- ->where($baseDateWhere)
- ->select('user_id')
- ->column() ?: [];
- $now = time();
- // 找差集
- $noExistUserIds = array_diff($parentUserIds, $findParentUserIds);
- if ($noExistUserIds) {
- $batchInsertData = [];
- $batchInsertField = ['mall_id', 'user_id', 'created_at', 'updated_at'];
- if (static::IS_BY_DATE) {
- $batchInsertField[] = 'date';
- }
- foreach ($noExistUserIds as $key => $noExistUserId) {
- $batchInsertData[$key] = [
- 'mall_id' => $baseData['mall_id'],
- 'user_id' => $noExistUserId,
- 'created_at' => $now,
- 'updated_at' => $now,
- ];
- if (static::IS_BY_DATE) {
- $batchInsertData[$key]['date'] = $baseData['date'];
- }
- }
- try {
- Yii::$app->db->createCommand()->batchInsert(
- static::tableName(),
- $batchInsertField,
- array_values($batchInsertData)
- )->execute();
- } catch (Exception $e) {
- $desc = sprintf(
- '团队统计,插入基础统计数据失败,data: %s',
- json_encode([
- 'class' => static::class,
- 'agrs' => func_get_args(),
- 'saveData' => array_merge(['tableName' => static::tableName()], compact('batchInsertField', 'batchInsertData'))
- ])
- );
- Yii::error(FormatHelper::exception($e, $desc));
- }
- }
- [
- 'allowSaveTeamData' => $allowSaveTeamData,
- 'allowSaveDirectData' => $allowSaveDirectData,
- 'allowSaveIndirectData' => $allowSaveIndirectData
- ] = self::getAllowSaveData($isIncr, $teamData, $directData, $indirectData);
- try {
- // 群组总业绩、群组产品总额、群组订单总数。(不包含自己)
- if ($allowSaveTeamData) {
- $baseDateWhere['user_id'] = $parentUserIds;
- static::updateAllCounters($allowSaveTeamData, $baseDateWhere);
- }
- // 保存直推数据
- if ($parentId && $allowSaveDirectData) {
- $baseDateWhere['user_id'] = $parentId;
- static::updateAllCounters($allowSaveDirectData, $baseDateWhere);
- }
- // 保存间推数据
- if ($secondParentId && $allowSaveIndirectData) {
- $baseDateWhere['user_id'] = $secondParentId;
- static::updateAllCounters($allowSaveIndirectData, $baseDateWhere);
- }
- } catch (Exception $e) {
- $desc = sprintf(
- '保存团队统计数据失败,data: %s',
- json_encode([
- 'class' => static::class,
- 'agrs' => func_get_args(),
- 'saveData' => compact('allowSaveTeamData', 'allowSaveDirectData', 'allowSaveIndirectData')
- ])
- );
- Yii::error(FormatHelper::exception($e, $desc));
- return false;
- }
- return true;
- }
- /**
- * 获取允许操作的字段
- *
- * @param bool $isIncr
- * @param array $teamData
- * @param array $directData
- * @param array $indirectData
- *
- * @return array
- */
- protected static function getAllowSaveData(bool $isIncr, array $teamData, array $directData, array $indirectData): array
- {
- $allowSaveTeamData = [];
- // 直推数据
- $allowSaveDirectData = [];
- // 间推数据
- $allowSaveIndirectData = [];
- // 允许操作的字段
- $allowUpdateField = $isIncr ? static::ALLOW_INCR_FIELD : static::ALLOW_DECR_FIELD;
- $model = new static;
- foreach ($model as $field => $_) {
- !empty($teamData[$field]) && in_array($field, $allowUpdateField, true) && $allowSaveTeamData[$field] = $teamData[$field];
- !empty($directData[$field]) && in_array($field, $allowUpdateField, true) && $allowSaveDirectData[$field] = $directData[$field];
- !empty($indirectData[$field]) && in_array($field, $allowUpdateField, true) && $allowSaveIndirectData[$field] = $indirectData[$field];
- }
- return compact('allowSaveTeamData', 'allowSaveDirectData', 'allowSaveIndirectData');
- }
- }
|