request->param('page', 1); $limit = $this->request->param('limit', 10); $keyword = $this->request->param('keyword', ''); $companyId = $this->getUserInfo('companyId'); $package = Db::name('traffic_source_package')->alias('tsp') ->join('traffic_source_package_item tspi', 'tspi.packageId=tsp.id', 'left') ->whereIn('tsp.companyId', [$companyId, 0]) ->field('tsp.id,tsp.name,tsp.description,tsp.pic,tsp.isSys as type,tsp.createTime,count(tspi.id) as num') ->group('tsp.id'); if (!empty($keyword)) { $package->where('tsp.name|tsp.description', 'like', '%' . $keyword . '%'); } $list = $package->page($page, $limit)->order('isSys ASC,id DESC')->select(); $total = $package->count(); $rfmRule = 'default'; foreach ($list as $k => &$v) { if ($v['type'] != 1) { $v['createTime'] = !empty($v['createTime']) ? formatRelativeTime($v['createTime']) : ''; }else{ $v['createTime'] = ''; } // RFM 评分(示例:以创建时间近似最近活跃,num 近似频次;金额若无则为 0) $recencyDays = isset($v['createTime']) && is_numeric($v['createTime']) ? floor((time() - (int)$v['createTime']) / 86400) : null; // 如果上方被格式化为文本,则尝试从原始结果集取原值 if (!is_numeric($recencyDays) || $recencyDays === null) { $rawCreate = isset($list[$k]['createTime']) ? $list[$k]['createTime'] : null; $recencyDays = is_numeric($rawCreate) ? floor((time() - (int)$rawCreate) / 86400) : 9999; } $frequency = (int)($v['num'] ?? 0); $monetary = (float)($v['monetary'] ?? 0); $scores = RFMController::calcRfmScores($recencyDays, $frequency, $monetary); $v['R'] = $scores['R']; $v['F'] = $scores['F']; $v['M'] = $scores['M']; $v['RFM'] = $scores['R'] + $scores['F'] + $scores['M']; } unset($v); $data = [ 'total' => $total, 'list' => $list, ]; return ResponseHelper::success($data); } }