| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- <?php
- namespace app\common\utils;
- use app\common\dao\profit\ProductPvDao;
- use app\common\dao\store\order\StoreCartDao;
- use app\common\dao\store\order\StoreOrderDao;
- use app\common\dao\user\UserDao;
- use app\common\enum\store\StoreOrderEnum;
- /**
- * PV业绩计算工具类
- *
- * 用于计算用户的业绩(PV)值,基于订单和购物车数据进行统计
- * PV值根据商品配置的PV系数和购买数量计算得出
- */
- class Pv
- {
- /**
- * 商户ID,默认为496
- * @var int
- */
- private $merId = 496;
- /**
- * 订单状态数组,包含有效的订单状态值
- * 0,1,2,3 可能代表:待付款、已付款、已发货、已完成等状态
- * @var array
- */
- private $status = [
- StoreOrderEnum::STATUS['WAITING_SHIPMENT']['code'],
- StoreOrderEnum::STATUS['WAITING_RECEIVE']['code'],
- StoreOrderEnum::STATUS['WAITING_EVALUATION']['code'],
- StoreOrderEnum::STATUS['COMPLETED']['code']
- ];
- /**
- * 需要排除的测试用户ID列表
- * 在计算业绩时需要过滤掉的测试用户
- * @var array
- */
- private $removeUserIdList;
- /**
- * 订单数据访问对象
- * @var StoreOrderDao
- */
- public $storeOrderDao;
- /**
- * 购物车数据访问对象
- * @var StoreCartDao
- */
- public $cartDao;
- /**
- * 用户数据访问对象
- * @var UserDao
- */
- public $userDao;
- public $pvDao;
- /**
- * 构造函数
- * 初始化数据访问对象和测试用户列表
- */
- public function __construct()
- {
- $this->storeOrderDao = new StoreOrderDao();
- $this->cartDao = new StoreCartDao();
- $this->userDao = new UserDao();
- $this->pvDao = new ProductPvDao();
- $this->removeUserIdList = $this->getRemoveUserIdList();
- }
- /**
- * 获取商品PV配置
- *
- * 返回商品ID到PV系数的映射数组
- * PV系数表示每个商品对应的业绩值
- *
- * @return int[] 商品PV配置数组,格式:[商品ID => PV系数]
- */
- public function getPvConfig(): array
- {
- return $this->pvDao->getData();
- }
- /**
- * 计算用户业绩(PV)
- *
- * 根据用户ID和时间范围计算业绩值
- * 流程:获取订单数据 → 获取购物车数据 → 统计商品数量 → 计算PV总值
- *
- * @param array $userId 用户ID数组,默认为空数组
- * @param int $startTime 开始时间戳,0表示无限制
- * @param int $endTime 结束时间戳,0表示无限制
- * @return void 直接输出计算结果(使用dd函数)
- */
- public function countPv($userId = [], $startTime = 0, $endTime = 0): void
- {
- // 测试用户id(硬编码,实际应该使用传入的参数)
- // $userId = [1592];
- // 时间范围示例(注释掉的代码)
- // $startTime = '2025-9-8';
- // $endTime = '2025-9-11';
- // 获取订单数据(过滤掉测试用户)
- $orderData = $this->storeOrderDao->getDataForPv(
- $userId,
- $startTime,
- $endTime,
- $this->merId,
- $this->status,
- $this->removeUserIdList
- );
- // 提取所有购物车ID
- $cartIds = array_column($orderData, 'cart_id');
- // 根据购物车ID获取购物车数据
- $cartData = $this->cartDao->getDataByIds($cartIds);
- // 统计每个商品的出现次数
- $productCount = $this->countProductIds($cartData);
- // 根据商品数量和PV配置计算总PV值
- $pv = $this->countResult($productCount);
- // 输出计算结果(调试用)
- dd($pv);
- }
- /**
- * 获取需要排除的测试用户ID列表
- *
- * 从用户DAO获取标记为测试用户的ID列表
- * 这些用户在计算业绩时会被排除
- *
- * @return array 测试用户ID数组
- */
- private function getRemoveUserIdList(): array
- {
- return $this->userDao->getTestUser();
- }
- /**
- * 统计购物车数据中商品ID的出现次数
- *
- * 遍历购物车数据,统计每个商品ID的购买次数
- *
- * @param array $cartData 购物车数据数组,包含商品信息
- * @return array 商品ID统计结果,格式:[商品ID => 购买次数]
- */
- private function countProductIds(array $cartData): array
- {
- $productIdCounts = [];
- foreach ($cartData as $cartItem) {
- $productId = $cartItem['product_id'];
- if (isset($productIdCounts[$productId])) {
- // 如果商品已存在,增加计数
- $productIdCounts[$productId]++;
- } else {
- // 如果商品不存在,初始化计数为1
- $productIdCounts[$productId] = 1;
- }
- }
- return $productIdCounts;
- }
- /**
- * 计算最终PV结果
- *
- * 根据商品购买次数和PV配置计算总业绩值
- * 公式:总PV = Σ(商品购买次数 × 商品PV系数)
- *
- * @param array $productCount 商品购买次数数组,格式:[商品ID => 购买次数]
- * @return float|int 总PV值
- */
- private function countResult(array $productCount)
- {
- // 获取PV配置
- $pvConfig = $this->getPvConfig();
- $totalPv = 0;
- // 遍历每个商品计算PV贡献
- foreach ($productCount as $productId => $count) {
- if (isset($pvConfig[$productId])) {
- // 如果商品有配置PV系数,计算该商品的PV贡献
- $totalPv += $count * $pvConfig[$productId];
- }
- // 如果没有配置PV系数的商品,不计入业绩
- }
- return $totalPv;
- }
- }
|