2025-05-19 16:30:19 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace app\cunkebao\controller\plan;
|
|
|
|
|
|
|
2025-08-11 14:11:11 +08:00
|
|
|
|
use app\cunkebao\controller\BaseController;
|
2025-05-19 16:30:19 +08:00
|
|
|
|
use library\ResponseHelper;
|
|
|
|
|
|
use think\Db;
|
|
|
|
|
|
use think\facade\Request;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获客场景控制器
|
|
|
|
|
|
*/
|
2025-08-11 14:11:11 +08:00
|
|
|
|
class PostCreateAddFriendPlanV1Controller extends BaseController
|
2025-05-19 16:30:19 +08:00
|
|
|
|
{
|
2025-05-20 11:25:28 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 生成唯一API密钥
|
2025-08-13 17:02:36 +08:00
|
|
|
|
*
|
2025-06-16 15:42:36 +08:00
|
|
|
|
* @return string
|
|
|
|
|
|
*/
|
2025-07-28 17:40:23 +08:00
|
|
|
|
public function generateApiKey()
|
2025-06-16 15:42:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 生成5组随机字符串,每组5个字符
|
|
|
|
|
|
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
|
|
|
|
$apiKey = '';
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
for ($i = 0; $i < 5; $i++) {
|
|
|
|
|
|
$segment = '';
|
|
|
|
|
|
for ($j = 0; $j < 5; $j++) {
|
|
|
|
|
|
$segment .= $chars[mt_rand(0, strlen($chars) - 1)];
|
|
|
|
|
|
}
|
|
|
|
|
|
$apiKey .= ($i > 0 ? '-' : '') . $segment;
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
// 检查是否已存在
|
|
|
|
|
|
$exists = Db::name('customer_acquisition_task')
|
|
|
|
|
|
->where('apiKey', $apiKey)
|
|
|
|
|
|
->find();
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
if ($exists) {
|
|
|
|
|
|
// 如果已存在,递归重新生成
|
|
|
|
|
|
return $this->generateApiKey();
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
return $apiKey;
|
|
|
|
|
|
}
|
2025-05-20 11:25:28 +08:00
|
|
|
|
|
2025-05-19 16:30:19 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 添加计划任务
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return \think\response\Json
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function index()
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
2025-06-16 15:42:36 +08:00
|
|
|
|
$params = $this->request->param();
|
2025-07-03 18:14:53 +08:00
|
|
|
|
|
2025-05-19 16:30:19 +08:00
|
|
|
|
// 验证必填字段
|
2025-06-17 15:56:02 +08:00
|
|
|
|
if (empty($params['name'])) {
|
2025-05-19 16:30:19 +08:00
|
|
|
|
return ResponseHelper::error('计划名称不能为空', 400);
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-07-25 16:25:33 +08:00
|
|
|
|
if (empty($params['sceneId'])) {
|
2025-05-19 16:30:19 +08:00
|
|
|
|
return ResponseHelper::error('场景ID不能为空', 400);
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-09-12 09:40:13 +08:00
|
|
|
|
if (empty($params['deviceGroups'])) {
|
2025-06-16 15:42:36 +08:00
|
|
|
|
return ResponseHelper::error('请选择设备', 400);
|
2025-05-19 16:30:19 +08:00
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2026-01-08 10:45:41 +08:00
|
|
|
|
// 拉群配置校验
|
|
|
|
|
|
// groupInviteEnabled:拉群开关(0/1)
|
|
|
|
|
|
// groupName:群名称
|
|
|
|
|
|
// groupFixedMembers:固定成员(数组)
|
|
|
|
|
|
$groupInviteEnabled = !empty($params['groupInviteEnabled']) ? 1 : 0;
|
|
|
|
|
|
if ($groupInviteEnabled) {
|
|
|
|
|
|
if (empty($params['groupName'])) {
|
|
|
|
|
|
return ResponseHelper::error('拉群群名不能为空', 400);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (empty($params['groupFixedMembers']) || !is_array($params['groupFixedMembers'])) {
|
|
|
|
|
|
return ResponseHelper::error('固定成员不能为空', 400);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-17 16:20:46 +08:00
|
|
|
|
$companyId = $this->getUserInfo('companyId');
|
|
|
|
|
|
|
|
|
|
|
|
// 处理分销配置
|
|
|
|
|
|
$distributionConfig = $this->processDistributionConfig($params, $companyId);
|
2025-06-16 15:42:36 +08:00
|
|
|
|
|
|
|
|
|
|
// 归类参数
|
|
|
|
|
|
$msgConf = isset($params['messagePlans']) ? $params['messagePlans'] : [];
|
|
|
|
|
|
$tagConf = [
|
|
|
|
|
|
'scenarioTags' => $params['scenarioTags'] ?? [],
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'customTags' => $params['customTags'] ?? [],
|
2025-06-16 15:42:36 +08:00
|
|
|
|
];
|
|
|
|
|
|
$reqConf = [
|
2025-09-12 09:40:13 +08:00
|
|
|
|
'device' => $params['deviceGroups'] ?? [],
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'remarkType' => $params['remarkType'] ?? '',
|
|
|
|
|
|
'greeting' => $params['greeting'] ?? '',
|
2025-06-16 15:42:36 +08:00
|
|
|
|
'addFriendInterval' => $params['addFriendInterval'] ?? '',
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'startTime' => $params['startTime'] ?? '',
|
|
|
|
|
|
'endTime' => $params['endTime'] ?? '',
|
2025-06-16 15:42:36 +08:00
|
|
|
|
];
|
|
|
|
|
|
// 其余参数归为sceneConf
|
|
|
|
|
|
$sceneConf = $params;
|
|
|
|
|
|
unset(
|
2025-07-07 14:54:01 +08:00
|
|
|
|
$sceneConf['id'],
|
|
|
|
|
|
$sceneConf['apiKey'],
|
|
|
|
|
|
$sceneConf['userId'],
|
|
|
|
|
|
$sceneConf['status'],
|
|
|
|
|
|
$sceneConf['planId'],
|
2025-06-17 15:56:02 +08:00
|
|
|
|
$sceneConf['name'],
|
|
|
|
|
|
$sceneConf['sceneId'],
|
2025-06-16 15:42:36 +08:00
|
|
|
|
$sceneConf['messagePlans'],
|
|
|
|
|
|
$sceneConf['scenarioTags'],
|
|
|
|
|
|
$sceneConf['customTags'],
|
|
|
|
|
|
$sceneConf['device'],
|
2025-07-07 14:54:01 +08:00
|
|
|
|
$sceneConf['orderTableFileName'],
|
|
|
|
|
|
$sceneConf['userInfo'],
|
|
|
|
|
|
$sceneConf['textUrl'],
|
2025-06-16 15:42:36 +08:00
|
|
|
|
$sceneConf['remarkType'],
|
|
|
|
|
|
$sceneConf['greeting'],
|
|
|
|
|
|
$sceneConf['addFriendInterval'],
|
|
|
|
|
|
$sceneConf['startTime'],
|
2025-07-07 14:54:01 +08:00
|
|
|
|
$sceneConf['orderTableFile'],
|
2025-12-17 16:20:46 +08:00
|
|
|
|
$sceneConf['endTime'],
|
|
|
|
|
|
$sceneConf['distributionEnabled'],
|
|
|
|
|
|
$sceneConf['distributionChannels'],
|
|
|
|
|
|
$sceneConf['customerRewardAmount'],
|
2026-01-08 10:45:41 +08:00
|
|
|
|
$sceneConf['addFriendRewardAmount'],
|
|
|
|
|
|
// 拉群相关字段单独存表,不放到 sceneConf
|
|
|
|
|
|
$sceneConf['groupInviteEnabled'],
|
|
|
|
|
|
$sceneConf['groupName'],
|
|
|
|
|
|
$sceneConf['groupFixedMembers']
|
2025-06-16 15:42:36 +08:00
|
|
|
|
);
|
2025-05-19 16:30:19 +08:00
|
|
|
|
|
2025-12-17 16:20:46 +08:00
|
|
|
|
// 将分销配置添加到sceneConf中
|
|
|
|
|
|
$sceneConf['distribution'] = $distributionConfig;
|
|
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
// 构建数据
|
|
|
|
|
|
$data = [
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'name' => $params['name'],
|
|
|
|
|
|
'sceneId' => $params['sceneId'],
|
2025-06-16 15:42:36 +08:00
|
|
|
|
'sceneConf' => json_encode($sceneConf, JSON_UNESCAPED_UNICODE),
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'reqConf' => json_encode($reqConf, JSON_UNESCAPED_UNICODE),
|
|
|
|
|
|
'msgConf' => json_encode($msgConf, JSON_UNESCAPED_UNICODE),
|
|
|
|
|
|
'tagConf' => json_encode($tagConf, JSON_UNESCAPED_UNICODE),
|
|
|
|
|
|
'userId' => $this->getUserInfo('id'),
|
2025-08-11 14:11:11 +08:00
|
|
|
|
'companyId' => $this->getUserInfo('companyId'),
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'status' => !empty($params['status']) ? 1 : 0,
|
2026-01-15 14:24:25 +08:00
|
|
|
|
// 计划类型:0=全局,1=独立(默认)
|
|
|
|
|
|
'planType' => isset($params['planType']) ? intval($params['planType']) : 1,
|
2026-01-08 10:45:41 +08:00
|
|
|
|
// 拉群配置
|
|
|
|
|
|
'groupInviteEnabled' => $groupInviteEnabled,
|
|
|
|
|
|
'groupName' => $params['groupName'] ?? '',
|
|
|
|
|
|
'groupFixedMembers' => !empty($params['groupFixedMembers'])
|
|
|
|
|
|
? json_encode($params['groupFixedMembers'], JSON_UNESCAPED_UNICODE)
|
|
|
|
|
|
: json_encode([], JSON_UNESCAPED_UNICODE),
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'apiKey' => $this->generateApiKey(), // 生成API密钥
|
|
|
|
|
|
'createTime' => time(),
|
|
|
|
|
|
'updateTime' => time(),
|
2025-06-16 15:42:36 +08:00
|
|
|
|
];
|
2025-05-19 16:30:19 +08:00
|
|
|
|
|
2025-07-25 16:25:33 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
try {
|
2025-07-06 00:17:24 +08:00
|
|
|
|
Db::startTrans();
|
2025-06-16 15:42:36 +08:00
|
|
|
|
// 插入数据
|
|
|
|
|
|
$planId = Db::name('customer_acquisition_task')->insertGetId($data);
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
if (!$planId) {
|
|
|
|
|
|
throw new \Exception('添加计划失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-03 18:14:53 +08:00
|
|
|
|
|
|
|
|
|
|
//订单
|
2025-08-13 17:02:36 +08:00
|
|
|
|
if ($params['sceneId'] == 2) {
|
2025-09-12 09:40:13 +08:00
|
|
|
|
if (!empty($params['orderFileUrl'])) {
|
2025-07-03 18:14:53 +08:00
|
|
|
|
// 先下载到本地临时文件,再分析,最后删除
|
2025-09-12 09:40:13 +08:00
|
|
|
|
$originPath = $params['orderFileUrl'];
|
2025-07-03 18:14:53 +08:00
|
|
|
|
$tmpFile = tempnam(sys_get_temp_dir(), 'order_');
|
|
|
|
|
|
// 判断是否为远程文件
|
|
|
|
|
|
if (preg_match('/^https?:\/\//i', $originPath)) {
|
|
|
|
|
|
// 远程URL,下载到本地
|
|
|
|
|
|
$fileContent = file_get_contents($originPath);
|
|
|
|
|
|
if ($fileContent === false) {
|
|
|
|
|
|
exit('远程文件下载失败: ' . $originPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
file_put_contents($tmpFile, $fileContent);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 本地文件,直接copy
|
|
|
|
|
|
if (!file_exists($originPath)) {
|
|
|
|
|
|
exit('文件不存在: ' . $originPath);
|
|
|
|
|
|
}
|
|
|
|
|
|
copy($originPath, $tmpFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 解析临时文件
|
|
|
|
|
|
$ext = strtolower(pathinfo($originPath, PATHINFO_EXTENSION));
|
|
|
|
|
|
$rows = [];
|
|
|
|
|
|
if (in_array($ext, ['xls', 'xlsx'])) {
|
|
|
|
|
|
// 直接用composer自动加载的PHPExcel
|
|
|
|
|
|
$excel = \PHPExcel_IOFactory::load($tmpFile);
|
|
|
|
|
|
$sheet = $excel->getActiveSheet();
|
|
|
|
|
|
$data = $sheet->toArray();
|
|
|
|
|
|
if (count($data) > 1) {
|
|
|
|
|
|
array_shift($data); // 去掉表头
|
|
|
|
|
|
}
|
2025-07-05 16:34:57 +08:00
|
|
|
|
|
2025-07-03 18:14:53 +08:00
|
|
|
|
foreach ($data as $cols) {
|
2025-07-05 16:34:57 +08:00
|
|
|
|
$rows[] = [
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'name' => isset($cols[0]) ? trim($cols[0]) : '',
|
|
|
|
|
|
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
|
|
|
|
|
|
'wechatId' => isset($cols[2]) ? trim($cols[2]) : '',
|
|
|
|
|
|
'source' => isset($cols[3]) ? trim($cols[3]) : '',
|
2025-07-05 16:34:57 +08:00
|
|
|
|
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
|
2025-07-05 16:34:57 +08:00
|
|
|
|
];
|
2025-07-03 18:14:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
} elseif ($ext === 'csv') {
|
|
|
|
|
|
$content = file_get_contents($tmpFile);
|
|
|
|
|
|
$lines = preg_split('/\r\n|\r|\n/', $content);
|
|
|
|
|
|
if (count($lines) > 1) {
|
|
|
|
|
|
array_shift($lines); // 去掉表头
|
|
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
|
|
if (trim($line) === '') continue;
|
|
|
|
|
|
$cols = str_getcsv($line);
|
|
|
|
|
|
if (count($cols) >= 6) {
|
|
|
|
|
|
$rows[] = [
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'name' => isset($cols[0]) ? trim($cols[0]) : '',
|
|
|
|
|
|
'phone' => isset($cols[1]) ? trim($cols[1]) : '',
|
|
|
|
|
|
'wechatId' => isset($cols[2]) ? trim($cols[2]) : '',
|
|
|
|
|
|
'source' => isset($cols[3]) ? trim($cols[3]) : '',
|
2025-07-05 16:34:57 +08:00
|
|
|
|
'orderAmount' => isset($cols[4]) ? trim($cols[4]) : '',
|
2025-08-13 17:02:36 +08:00
|
|
|
|
'orderDate' => isset($cols[5]) ? trim($cols[5]) : '',
|
2025-07-03 18:14:53 +08:00
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
unlink($tmpFile);
|
|
|
|
|
|
exit('暂不支持的文件类型: ' . $ext);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 删除临时文件
|
|
|
|
|
|
unlink($tmpFile);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-13 17:02:36 +08:00
|
|
|
|
//电话获客
|
|
|
|
|
|
if ($params['sceneId'] == 5) {
|
|
|
|
|
|
$rows = Db::name('call_recording')
|
|
|
|
|
|
->where('companyId', $this->getUserInfo('companyId'))
|
|
|
|
|
|
->group('phone')
|
|
|
|
|
|
->field('id,phone')
|
|
|
|
|
|
->select();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-07 11:56:04 +08:00
|
|
|
|
//群获客
|
2025-08-12 15:02:00 +08:00
|
|
|
|
if ($params['sceneId'] == 7) {
|
|
|
|
|
|
if (!empty($params['wechatGroups']) && is_array($params['wechatGroups'])) {
|
|
|
|
|
|
$rows = Db::name('wechat_group_member')->alias('gm')
|
|
|
|
|
|
->join('wechat_account wa', 'gm.identifier = wa.wechatId')
|
|
|
|
|
|
->whereIn('gm.groupId', $params['wechatGroups'])
|
|
|
|
|
|
->group('gm.identifier')
|
|
|
|
|
|
->column('wa.id,wa.wechatId,wa.alias,wa.phone');
|
2025-08-13 17:02:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-12 15:02:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-08-13 17:02:36 +08:00
|
|
|
|
if (in_array($params['sceneId'], [2, 5, 7]) && !empty($rows) && is_array($rows)) {
|
|
|
|
|
|
// 1000条为一组进行批量处理
|
|
|
|
|
|
$batchSize = 1000;
|
|
|
|
|
|
$totalRows = count($rows);
|
|
|
|
|
|
|
|
|
|
|
|
for ($i = 0; $i < $totalRows; $i += $batchSize) {
|
|
|
|
|
|
$batchRows = array_slice($rows, $i, $batchSize);
|
|
|
|
|
|
|
|
|
|
|
|
if (!empty($batchRows)) {
|
|
|
|
|
|
// 1. 提取当前批次的phone
|
|
|
|
|
|
$phones = [];
|
|
|
|
|
|
foreach ($batchRows as $row) {
|
|
|
|
|
|
if (!empty($row['phone'])) {
|
|
|
|
|
|
$phone = $row['phone'];
|
|
|
|
|
|
} elseif (!empty($row['alias'])) {
|
|
|
|
|
|
$phone = $row['alias'];
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$phone = $row['wechatId'];
|
2025-08-12 15:02:00 +08:00
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
if (!empty($phone)) {
|
|
|
|
|
|
$phones[] = $phone;
|
2025-08-12 15:02:00 +08:00
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
}
|
2025-08-12 15:02:00 +08:00
|
|
|
|
|
2025-08-13 17:02:36 +08:00
|
|
|
|
// 2. 批量查询已存在的phone
|
|
|
|
|
|
$existingPhones = [];
|
|
|
|
|
|
if (!empty($phones)) {
|
|
|
|
|
|
$existing = Db::name('task_customer')
|
|
|
|
|
|
->where('task_id', $planId)
|
|
|
|
|
|
->where('phone', 'in', $phones)
|
|
|
|
|
|
->field('phone')
|
|
|
|
|
|
->select();
|
|
|
|
|
|
$existingPhones = array_column($existing, 'phone');
|
|
|
|
|
|
}
|
2025-08-07 11:56:04 +08:00
|
|
|
|
|
2025-08-13 17:02:36 +08:00
|
|
|
|
// 3. 过滤出新数据,批量插入
|
|
|
|
|
|
$newData = [];
|
|
|
|
|
|
foreach ($batchRows as $row) {
|
|
|
|
|
|
if (!empty($row['phone'])) {
|
|
|
|
|
|
$phone = $row['phone'];
|
|
|
|
|
|
} elseif (!empty($row['alias'])) {
|
|
|
|
|
|
$phone = $row['alias'];
|
|
|
|
|
|
} else {
|
|
|
|
|
|
$phone = $row['wechatId'];
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!empty($phone) && !in_array($phone, $existingPhones)) {
|
|
|
|
|
|
$newData[] = [
|
|
|
|
|
|
'task_id' => $planId,
|
|
|
|
|
|
'name' => '',
|
|
|
|
|
|
'source' => '场景获客_' . $params['name'] ?? '',
|
|
|
|
|
|
'phone' => $phone,
|
|
|
|
|
|
'tags' => json_encode([], JSON_UNESCAPED_UNICODE),
|
|
|
|
|
|
'siteTags' => json_encode([], JSON_UNESCAPED_UNICODE),
|
|
|
|
|
|
'createTime' => time(),
|
|
|
|
|
|
];
|
2025-08-12 15:02:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
|
|
|
|
|
// 4. 批量插入新数据
|
|
|
|
|
|
if (!empty($newData)) {
|
|
|
|
|
|
Db::name('task_customer')->insertAll($newData);
|
|
|
|
|
|
}
|
2025-08-12 15:02:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-07 11:56:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-06 00:17:24 +08:00
|
|
|
|
Db::commit();
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
return ResponseHelper::success(['planId' => $planId], '添加计划任务成功');
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-06-16 15:42:36 +08:00
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
// 回滚事务
|
|
|
|
|
|
Db::rollback();
|
|
|
|
|
|
throw $e;
|
2025-05-19 16:30:19 +08:00
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-05-19 16:30:19 +08:00
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
return ResponseHelper::error('系统错误: ' . $e->getMessage(), 500);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-22 15:50:52 +08:00
|
|
|
|
|
2025-08-13 17:02:36 +08:00
|
|
|
|
/**
|
2025-05-22 15:50:52 +08:00
|
|
|
|
* 验证JSON格式是否正确
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $string
|
|
|
|
|
|
* @return bool
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function validateJson($string)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (empty($string)) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2025-08-13 17:02:36 +08:00
|
|
|
|
|
2025-05-22 15:50:52 +08:00
|
|
|
|
json_decode($string);
|
|
|
|
|
|
return (json_last_error() == JSON_ERROR_NONE);
|
|
|
|
|
|
}
|
2025-12-17 16:20:46 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 处理分销配置
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param array $params 请求参数
|
|
|
|
|
|
* @param int $companyId 公司ID
|
|
|
|
|
|
* @return array 分销配置
|
|
|
|
|
|
*/
|
|
|
|
|
|
private function processDistributionConfig($params, $companyId)
|
|
|
|
|
|
{
|
|
|
|
|
|
$distributionEnabled = !empty($params['distributionEnabled']) ? true : false;
|
|
|
|
|
|
|
|
|
|
|
|
$config = [
|
|
|
|
|
|
'enabled' => $distributionEnabled,
|
|
|
|
|
|
'channels' => [],
|
|
|
|
|
|
'customerRewardAmount' => 0, // 获客奖励金额(分)
|
|
|
|
|
|
'addFriendRewardAmount' => 0, // 添加奖励金额(分)
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 如果未开启分销,直接返回默认配置
|
|
|
|
|
|
if (!$distributionEnabled) {
|
|
|
|
|
|
return $config;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证渠道ID
|
|
|
|
|
|
$channelIds = $params['distributionChannels'] ?? [];
|
|
|
|
|
|
if (empty($channelIds) || !is_array($channelIds)) {
|
|
|
|
|
|
throw new \Exception('请选择至少一个分销渠道');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 查询有效的渠道(只保留存在且已启用的渠道)
|
|
|
|
|
|
$channels = Db::name('distribution_channel')
|
|
|
|
|
|
->where([
|
|
|
|
|
|
['id', 'in', $channelIds],
|
|
|
|
|
|
['companyId', '=', $companyId],
|
|
|
|
|
|
['status', '=', 'enabled'],
|
|
|
|
|
|
['deleteTime', '=', 0]
|
|
|
|
|
|
])
|
|
|
|
|
|
->field('id,code,name')
|
|
|
|
|
|
->select();
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有有效渠道,才报错
|
|
|
|
|
|
if (empty($channels)) {
|
|
|
|
|
|
throw new \Exception('所选的分销渠道均不存在或已被禁用,请重新选择');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 只保留有效的渠道ID
|
|
|
|
|
|
$config['channels'] = array_column($channels, 'id');
|
|
|
|
|
|
|
|
|
|
|
|
// 验证获客奖励金额(元转分)
|
|
|
|
|
|
$customerRewardAmount = isset($params['customerRewardAmount']) ? floatval($params['customerRewardAmount']) : 0;
|
|
|
|
|
|
if ($customerRewardAmount < 0) {
|
|
|
|
|
|
throw new \Exception('获客奖励金额不能为负数');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($customerRewardAmount > 0 && !preg_match('/^\d+(\.\d{1,2})?$/', (string)$customerRewardAmount)) {
|
|
|
|
|
|
throw new \Exception('获客奖励金额格式不正确,最多保留2位小数');
|
|
|
|
|
|
}
|
|
|
|
|
|
$config['customerRewardAmount'] = intval(round($customerRewardAmount * 100)); // 元转分
|
|
|
|
|
|
|
|
|
|
|
|
// 验证添加奖励金额(元转分)
|
|
|
|
|
|
$addFriendRewardAmount = isset($params['addFriendRewardAmount']) ? floatval($params['addFriendRewardAmount']) : 0;
|
|
|
|
|
|
if ($addFriendRewardAmount < 0) {
|
|
|
|
|
|
throw new \Exception('添加奖励金额不能为负数');
|
|
|
|
|
|
}
|
|
|
|
|
|
if ($addFriendRewardAmount > 0 && !preg_match('/^\d+(\.\d{1,2})?$/', (string)$addFriendRewardAmount)) {
|
|
|
|
|
|
throw new \Exception('添加奖励金额格式不正确,最多保留2位小数');
|
|
|
|
|
|
}
|
|
|
|
|
|
$config['addFriendRewardAmount'] = intval(round($addFriendRewardAmount * 100)); // 元转分
|
|
|
|
|
|
|
|
|
|
|
|
return $config;
|
|
|
|
|
|
}
|
2025-05-19 16:30:19 +08:00
|
|
|
|
}
|