Files
cunkebao_v3/Server/application/cunkebao/controller/TrafficController.php

321 lines
11 KiB
PHP
Raw Normal View History

2025-10-14 17:03:05 +08:00
<?php
namespace app\cunkebao\controller;
2025-10-20 14:22:20 +08:00
use app\common\model\TrafficSourcePackage;
use app\common\model\TrafficSourcePackageItem;
2025-10-14 17:03:05 +08:00
use library\ResponseHelper;
use think\Db;
use app\cunkebao\controller\RFMController;
class TrafficController extends BaseController
{
2025-10-20 14:22:20 +08:00
/**
* 流量池包
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
2025-10-14 17:03:05 +08:00
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']) : '';
2025-10-20 14:22:20 +08:00
} else {
2025-10-14 17:03:05 +08:00
$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);
}
2025-10-20 14:22:20 +08:00
/**
* 添加流量池
* @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);
}
2025-10-14 17:03:05 +08:00
}