Files
cunkebao_v3/Server/application/cunkebao/controller/TrafficController.php
2025-10-20 14:22:20 +08:00

321 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\cunkebao\controller;
use app\common\model\TrafficSourcePackage;
use app\common\model\TrafficSourcePackageItem;
use library\ResponseHelper;
use think\Db;
use app\cunkebao\controller\RFMController;
class TrafficController extends BaseController
{
/**
* 流量池包
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getPackage()
{
$page = $this->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);
}
/**
* 添加流量池
* @return \think\response\Json
* @throws \Exception
*/
public function addPackage()
{
$packageName = $this->request->param('packageName', '');
$description = $this->request->param('description', '');
$pic = $this->request->param('pic', '');
$companyId = $this->getUserInfo('companyId');
$userId = $this->getUserInfo('id');
if (empty($packageName)) {
return ResponseHelper::error('流量池名称不能为空');
}
$package = TrafficSourcePackage::where(['isDel' => 0, 'name' => $packageName])
->whereIn('companyId', [$companyId, 0])
->field('id,name')
->find();
if (!empty($package)) {
return ResponseHelper::error('该流量池名称已存在');
}
$packageId = TrafficSourcePackage::insertGetId([
'userId' => $userId,
'companyId' => $companyId,
'name' => $packageName,
'description' => $description,
'pic' => $pic,
'matchingRules' => json_encode([]),
'createTime' => time(),
'isDel' => 0,
]);
if (!empty($packageId)) {
return ResponseHelper::success($packageId, '该流量添加成功');
} else {
return ResponseHelper::error('该流量添加失败');
}
}
/**
* 编辑流量池
* @return \think\response\Json
* @throws \Exception
*/
public function editPackage()
{
$packageId = $this->request->param('packageId', '');
$packageName = $this->request->param('packageName', '');
$description = $this->request->param('description', '');
$pic = $this->request->param('pic', '');
$companyId = $this->getUserInfo('companyId');
$userId = $this->getUserInfo('id');
if (empty($packageId)) {
return ResponseHelper::error('流量池ID不能为空');
}
if (empty($packageName)) {
return ResponseHelper::error('流量池名称不能为空');
}
// 检查流量池是否存在且属于当前公司
$package = TrafficSourcePackage::where(['id' => $packageId, 'isDel' => 0])
->whereIn('companyId', [$companyId, 0])
->find();
if (empty($package)) {
return ResponseHelper::error('流量池不存在或已删除');
}
// 检查系统流量池是否可编辑
if ($package['isSys'] == 1) {
return ResponseHelper::error('系统流量池不允许编辑');
}
// 检查名称是否重复(排除当前记录)
$existPackage = TrafficSourcePackage::where(['isDel' => 0, 'name' => $packageName])
->whereIn('companyId', [$companyId, 0])
->where('id', '<>', $packageId)
->field('id,name')
->find();
if (!empty($existPackage)) {
return ResponseHelper::error('该流量池名称已存在');
}
// 更新流量池信息
$updateData = [
'name' => $packageName,
'updateTime' => time(),
];
// 更新描述字段(允许为空)
$updateData['description'] = $description;
// 更新图片字段(允许为空)
$updateData['pic'] = $pic;
$result = TrafficSourcePackage::where('id', $packageId)->update($updateData);
if ($result !== false) {
return ResponseHelper::success($packageId, '流量池编辑成功');
} else {
return ResponseHelper::error('流量池编辑失败');
}
}
/**
* 删除流量池(假删除)
* @return \think\response\Json
* @throws \Exception
*/
public function deletePackage()
{
$packageId = $this->request->param('packageId', '');
$companyId = $this->getUserInfo('companyId');
if (empty($packageId)) {
return ResponseHelper::error('流量池ID不能为空');
}
// 检查流量池是否存在且属于当前公司
$package = TrafficSourcePackage::where(['id' => $packageId, 'isDel' => 0])
->whereIn('companyId', [$companyId, 0])
->find();
if (empty($package)) {
return ResponseHelper::error('流量池不存在或已删除');
}
// 检查系统流量池是否可删除
if ($package['isSys'] == 1) {
return ResponseHelper::error('系统流量池不允许删除');
}
// 开启事务
Db::startTrans();
try {
// 执行流量池假删除
$result = TrafficSourcePackage::where('id', $packageId)->update([
'isDel' => 1,
'deleteTime' => time()
]);
if ($result === false) {
throw new \Exception('流量池删除失败');
}
// 删除流量池内容TrafficSourcePackageItem假删除
$itemResult = TrafficSourcePackageItem::where([
'packageId' => $packageId,
'companyId' => $companyId,
'isDel' => 0
])->update([
'isDel' => 1,
'deleteTime' => time()
]);
// 提交事务
Db::commit();
return ResponseHelper::success($packageId, '流量池及内容删除成功');
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
return ResponseHelper::error('删除失败:' . $e->getMessage());
}
}
/**
* 流量池列表
* @return \think\response\Json
* @throws \Exception
*/
public function getTrafficPoolList()
{
$page = $this->request->param('page', 1);
$limit = $this->request->param('limit', 10);
$keyword = $this->request->param('keyword', '');
$packageId = $this->request->param('packageId', '');
$companyId = $this->getUserInfo('companyId');
$userId = $this->getUserInfo('id');
if (empty($packageId)) {
return ResponseHelper::error('流量包id不能为空');
}
$trafficSourcePackage = TrafficSourcePackage::where(['id' => $packageId, 'isDel' => 0])->whereIn('companyId', [$companyId, 0])->find();
if (empty($trafficSourcePackage)) {
return ResponseHelper::error('流量包不存在或已删除');
}
$where = [
['tspi.companyId', '=', $companyId],
['tspi.packageId', '=', $packageId],
];
if (empty($keyword)) {
$where[] = ['wa.nickname|wa.phone|wa.alias|wa.wechatId|p.mobile|p.identifier', 'like', '%' . $keyword . '%'];
}
$query = TrafficSourcePackageItem::alias('tspi')
->field(
[
'p.id', 'p.identifier', 'p.mobile', 'p.wechatId', 'tspi.companyId',
'wa.nickname', 'wa.avatar', 'wa.gender', 'wa.phone', 'wa.alias'
]
)
->join('traffic_pool p', 'p.identifier=tspi.identifier', 'left')
->join('wechat_account wa', 'tspi.identifier=wa.wechatId', 'left')
->where($where);
$query->order('tspi.id DESC,p.id DESC')->group('p.identifier');
$list = $query->page($page, $limit)->select()->toArray();
$total = $query->count();
foreach ($list as $k => &$v) {
//流量池筛选
$package = TrafficSourcePackageItem::alias('tspi')
->join('traffic_source_package p', 'tspi.packageId=p.id AND tspi.companyId=p.companyId')
->where(['tspi.identifier' => $v['identifier']])
->whereIn('tspi.companyId', [0, $v['companyId']])
->column('p.name');
$v['packages'] = $package;
$v['phone'] = !empty($v['phone']) ? $v['phone'] : $v['mobile'];
unset($v['mobile']);
$scores = RFMController::calcRfmScores(30, 30, 30);
$v['R'] = $scores['R'];
$v['F'] = $scores['F'];
$v['M'] = $scores['M'];
$v['RFM'] = $scores['R'] + $scores['F'] + $scores['M'];
$v['money'] = 2222;
$v['msgCount'] = 2222;
$v['tag'] = ['test', 'test2'];
}
unset($v);
$data = ['list' => $list, 'total' => $total];
return ResponseHelper::success($data);
}
}